Beginning -font-ttf for -draw

This commit is contained in:
John Whitington 2023-07-07 14:34:51 +01:00
parent 64860ffbff
commit 7d1733b823
5 changed files with 48 additions and 73 deletions

View File

@ -2060,16 +2060,37 @@ let addopacity f =
let addsopacity f =
addop (Cpdfdraw.SOpacity f)
let embed_font () =
match args.font with
| StandardFont f ->
begin match args.embedstd14 with
| Some dirname ->
begin try
let fontfile, fontname =
let filename = hd (List.assoc f fontnames) in
Pdfio.bytes_of_string (contents_of_file (Filename.concat dirname filename)),
Filename.remove_extension filename
in
Cpdfembed.EmbedInfo {fontfile; fontname; encoding = args.fontencoding}
with
e -> error (Printf.sprintf "Can't load font for embedding: %s\n" (Printexc.to_string e))
end
| None ->
PreMadeFontPack (Cpdfembed.fontpack_of_standardfont (Pdftext.StandardFont (f, args.fontencoding)))
end
| OtherFont f ->
ExistingNamedFont
| FontToEmbed fontfile ->
EmbedInfo {fontfile; fontname = args.fontname; encoding = args.fontencoding}
let addtext s =
begin match !drawops with _::_::_ -> () | _ -> error "-text must be in a -bt / -et section" end;
let font = match args.font with StandardFont s -> s | _ -> error "-text: not a standard font" in
addop (Cpdfdraw.Font (font, args.fontsize));
addop (Cpdfdraw.Font (embed_font (), args.fontsize));
addop (Cpdfdraw.Text s)
let addspecialtext s =
begin match !drawops with _::_::_ -> () | _ -> error "-stext must be in a -bt / -et section" end;
let font = match args.font with StandardFont s -> s | _ -> error "-stext: not a standard font" in
addop (Cpdfdraw.Font (font, args.fontsize));
addop (Cpdfdraw.Font (embed_font (), args.fontsize));
addop (Cpdfdraw.SpecialText s)
let setstderrtostdout () =
@ -3454,30 +3475,6 @@ let warn_prerotate range pdf =
let prerotate range pdf =
Cpdfpage.upright ~fast:args.fast range pdf
let embed_font () =
match args.font with
| StandardFont f ->
(* FIXME proper error handling for missing file etc. *)
begin match args.embedstd14 with
| Some dirname ->
begin try
let fontfile, fontname =
let filename = hd (List.assoc f fontnames) in
Pdfio.bytes_of_string (contents_of_file (Filename.concat dirname filename)),
Filename.remove_extension filename
in
Cpdfembed.EmbedInfo {fontfile; fontname; encoding = args.fontencoding}
with
e -> error (Printf.sprintf "Can't load font for embedding: %s\n" (Printexc.to_string e))
end
| None ->
PreMadeFontPack (Cpdfembed.fontpack_of_standardfont (Pdftext.StandardFont (f, args.fontencoding)))
end
| OtherFont f ->
ExistingNamedFont
| FontToEmbed fontfile ->
EmbedInfo {fontfile; fontname = args.fontname; encoding = args.fontencoding}
let check_bookmarks_mistake () =
if args.merge_add_bookmarks_use_titles && not args.merge_add_bookmarks then
Pdfe.log "Warning: -merge-add-bookmarks-use-titles is for use with -merge-add-bookmarks\n"

View File

@ -38,7 +38,7 @@ type drawops =
| NewPage
| Opacity of float
| SOpacity of float
| Font of Pdftext.standard_font * float
| Font of Cpdfembed.cpdffont * float
| TextSection of drawops list
| Text of string
| SpecialText of string
@ -80,7 +80,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_font : Pdftext.font;
mutable current_fontpack : Cpdfembed.cpdffont;
mutable num : int}
let empty_res () =
@ -90,7 +90,10 @@ let empty_res () =
form_xobjects = null_hash ();
page_names = [];
time = Cpdfstrftime.dummy;
current_font = Pdftext.StandardFont (Pdftext.TimesRoman, Pdftext.WinAnsiEncoding);
current_fontpack =
Cpdfembed.PreMadeFontPack
(Cpdfembed.fontpack_of_standardfont
(Pdftext.StandardFont (Pdftext.TimesRoman, Pdftext.WinAnsiEncoding)));
num = 0}
let resstack =
@ -133,7 +136,12 @@ let process_specials pdf endpage filename bates batespad num page s =
Cpdfaddtext.process_text (res ()).time s pairs
let charcodes_of_utf8 s =
implode (map char_of_int (option_map (Pdftext.charcode_extractor_of_font_real (res ()).current_font) (Pdftext.codepoints_of_utf8 s)))
match (res ()).current_fontpack with
| PreMadeFontPack fontpack ->
let codepoints = Pdftext.codepoints_of_utf8 s in
let charcodes = option_map (Cpdfembed.get_char fontpack) codepoints in
implode (map (fun (c, _, _) -> char_of_int c) charcodes)
| _ -> failwith "charcodes_of_utf8: unknown font"
let extgstate kind v =
try Hashtbl.find (res ()).extgstates (kind, v) with
@ -222,7 +230,8 @@ let rec ops_of_drawop pdf endpage filename bates batespad num page = function
| Opacity v -> [Pdfops.Op_gs (extgstate "/ca" v)]
| SOpacity v -> [Pdfops.Op_gs (extgstate "/CA" v)]
| Font (s, f) ->
let font = Pdftext.StandardFont (s, Pdftext.WinAnsiEncoding) in
[]
(*let font = Pdftext.StandardFont (s, Pdftext.WinAnsiEncoding) in
let (n, _) =
try Hashtbl.find (res ()).fonts font with
Not_found ->
@ -233,7 +242,7 @@ let rec ops_of_drawop pdf endpage filename bates batespad num page = function
in
(res ()).current_font <- font;
(res ()).page_names <- n::(res ()).page_names;
[Pdfops.Op_Tf (n, f)]
[Pdfops.Op_Tf (n, f)]*)
| TextSection ops -> [Pdfops.Op_BT] @ ops_of_drawops pdf endpage filename bates batespad num page ops @ [Pdfops.Op_ET]
| Text s -> [Pdfops.Op_Tj (charcodes_of_utf8 s)]
| SpecialText s ->

View File

@ -35,7 +35,7 @@ type drawops =
| NewPage
| Opacity of float
| SOpacity of float
| Font of Pdftext.standard_font * float
| Font of Cpdfembed.cpdffont * float
| TextSection of drawops list
| Text of string
| SpecialText of string

View File

@ -2,12 +2,6 @@
encoding, adding the fontfiles to the PDF and returning a list of font objects,
together with a unicode codepoint --> (font number in list, charcode) table *)
(* FIXME: Really we want to create an interactive fontpack which creates fonts
when needed, but delays the actual production of the subset truetype data
until later. This will mean we don't need to pre-calculate the USED set. For
now, we just hack Cpdftoc, cpdfaddtext and cpdftextofpdf to pre-calculate
the subset. *)
type t = Pdftext.font list * (int, int * int) Hashtbl.t
type cpdffont =

View File

@ -4,10 +4,10 @@ open Pdfio
(* FIXME Proper widths for .notdef, and warn on .notdef being produced *)
(* FIXME Add suport for composite glyphs *)
(* FIXME No need for bitstream - everything is byte based, so we can use a normal input *)
(* FIXME Get rid of double-calling 1) make font then 2) collect chars then 3) subset it i.e the subset = [] stuff *)
(* FIXME All uses - add text / drawing / texttopdf / table of contents *)
(* FIXME Work across AND? *)
(* FIXME Make it work with -draw *)
(* FIXME Base on bytes not bits *)
(* FIXME proper error handling for missing file in cpdfcommand.embed_font *)
let dbg = ref false
let _ =
@ -43,7 +43,7 @@ let debug_t t =
Printf.printf "firstchar: %i\n" t.firstchar;
Printf.printf "lastchar: %i\n" t.lastchar;
Printf.printf "widths:"; Array.iter (Printf.printf " %i") t.widths; Printf.printf "\n";
Printf.printf "fontfile of length %i\n" (Pdfio.bytes_size t.subset_fontfile);
Printf.printf "fontfile of length %i\n" (bytes_size t.subset_fontfile);
Printf.printf "subset:"; iter (Printf.printf " U+%04X") t.subset; Printf.printf "\n";
Printf.printf "tounicode:\n";
begin match t.tounicode with
@ -162,7 +162,6 @@ let read_encoding_table fmt length version b =
if !dbg then Printf.printf "read_encoding_table: format 0\n";
let t = null_hash () in
for x = 0 to 255 do Hashtbl.add t x (read_byte b) done;
(*print_encoding_table 0 t;*)
t
| 4 ->
if !dbg then Printf.printf "read_encoding_table: format 4\n";
@ -476,23 +475,14 @@ let subset_font major minor tables indexToLocFormat subset encoding cmap loca mk
with
_ -> ())
newtables;
let obs = bytes_of_write_bitstream bs in
if !dbg then
begin
Printf.printf "Made subset font of length %i bytes\n" (bytes_size obs);
let o = open_out_bin ("fontout" ^ string_of_int (fonum ()) ^ ".ttf") in
output_string o (string_of_bytes obs);
close_out o
end;
obs
bytes_of_write_bitstream bs
let write_font filename data =
let fh = open_out_bin filename in
output_string fh (Pdfio.string_of_bytes data);
output_string fh (string_of_bytes data);
close_out fh
let find_main encoding subset =
(*(take subset 3, [drop subset 3])*)
let encoding_table = Pdftext.table_of_encoding encoding in
let first, rest =
List.partition
@ -502,12 +492,6 @@ let find_main encoding subset =
(first, splitinto 224 rest)
let parse ~subset data encoding =
if !dbg then
begin
Printf.printf "********Cpdftruetype.parse SUBSET is ";
iter (Printf.printf "U+%04X ") subset;
Printf.printf "\n"
end;
let mk_b byte_offset = bitbytes_of_input (let i = input_of_bytes data in i.seek_in byte_offset; i) in
let b = mk_b 0 in
let major, minor = read_fixed b in
@ -591,8 +575,7 @@ let parse ~subset data encoding =
let version = read_ushort b in
if !dbg then Printf.printf "subtable has format %i, length %i, version %i\n" fmt lngth version;
let got_glyphcodes = read_encoding_table fmt lngth version b in
(*if fmt = 4 then print_encoding_table 4 got_glyphcodes;*)
(*if fmt = 4 then *)Hashtbl.iter (Hashtbl.add !glyphcodes) got_glyphcodes
Hashtbl.iter (Hashtbl.add !glyphcodes) got_glyphcodes
done;
end;
let maxpoffset, maxplength =
@ -610,14 +593,6 @@ let parse ~subset data encoding =
| [] -> raise (Pdf.PDFError "No loca table found in TrueType font")
in
let subset_1, subsets_2 = find_main encoding subset in
(*if !dbg && subset <> [] then
begin
Printf.printf "***********Chars for main WinAnsiEncoding subset:\n";
iter (Printf.printf "U+%04X ") subset_1;
Printf.printf "\n***********Chars for higher subset:\n";
iter (Printf.printf "U+%04X ") subset_2;
Printf.printf "\n";
end;*)
let flags_1 = calculate_flags false italicangle in
let flags_2 = calculate_flags true italicangle in
let firstchar_1, lastchar_1 = calculate_limits subset_1 in