Removed the subset=[] stuff

This commit is contained in:
John Whitington 2023-07-07 16:33:07 +01:00
parent f4f83ceca7
commit 66f964bba3
1 changed files with 178 additions and 203 deletions

View File

@ -4,7 +4,7 @@ open Pdfio
(* FIXME Proper widths for .notdef, and warn on .notdef being produced *) (* FIXME Proper widths for .notdef, and warn on .notdef being produced *)
(* FIXME Add suport for composite glyphs *) (* FIXME Add suport for composite glyphs *)
(* FIXME Get rid of double-calling 1) make font then 2) collect chars then 3) subset it i.e the subset = [] stuff *) (* FIXME Make sure -add-text and -table-of-contents call subset once only *)
(* FIXME Make it work with -draw *) (* FIXME Make it work with -draw *)
(* FIXME Base on bytes not bits *) (* FIXME Base on bytes not bits *)
(* FIXME Make sure -embed-std14 works for all commands *) (* FIXME Make sure -embed-std14 works for all commands *)
@ -58,30 +58,23 @@ let debug_t t =
let required_tables = let required_tables =
["head"; "hhea"; "loca"; "cmap"; "maxp"; "cvt "; "glyf"; "prep"; "hmtx"; "fpgm"] ["head"; "hhea"; "loca"; "cmap"; "maxp"; "cvt "; "glyf"; "prep"; "hmtx"; "fpgm"]
(* 32-bit signed fixed-point number (16.16) returned as two ints *)
let read_fixed b = let read_fixed b =
let a = getval_31 b 16 in let a = getval_31 b 16 in
let b = getval_31 b 16 in let b = getval_31 b 16 in
a, b a, b
(* 16-bit unsigned integer *)
let read_ushort b = getval_31 b 16 let read_ushort b = getval_31 b 16
(* 32-bit unsigned integer *)
let read_ulong b = getval_32 b 32 let read_ulong b = getval_32 b 32
(* Signed byte *)
let read_byte b = getval_31 b 8 let read_byte b = getval_31 b 8
(* Signed short *)
let read_short b = sign_extend 16 (getval_31 b 16) let read_short b = sign_extend 16 (getval_31 b 16)
(* f2dot14 - 2 bit signed integer part, 14 bit unsigned fraction *)
let read_f2dot14 b = let read_f2dot14 b =
let v = read_ushort b in let v = read_ushort b in
float_of_int (sign_extend 2 (v lsr 14)) +. (float_of_int (v land 0x3FFF) /. 16384.) float_of_int (sign_extend 2 (v lsr 14)) +. (float_of_int (v land 0x3FFF) /. 16384.)
(* discard n bytes *)
let discard_bytes b n = let discard_bytes b n =
for x = 1 to n do ignore (getval_31 b 8) done for x = 1 to n do ignore (getval_31 b 8) done
@ -162,16 +155,11 @@ let read_encoding_table fmt length version b =
if !dbg then Printf.printf "********** format %i table has length, version %i, %i\n" fmt length version; if !dbg then Printf.printf "********** format %i table has length, version %i, %i\n" fmt length version;
match fmt with match fmt with
| 0 -> | 0 ->
if !dbg then Printf.printf "read_encoding_table: format 0\n";
let t = null_hash () in let t = null_hash () in
for x = 0 to 255 do Hashtbl.add t x (read_byte b) done; for x = 0 to 255 do Hashtbl.add t x (read_byte b) done;
t t
| 4 -> | 4 -> read_format_4_encoding_table b;
if !dbg then Printf.printf "read_encoding_table: format 4\n"; | 6 -> read_format_6_encoding_table b;
read_format_4_encoding_table b;
| 6 ->
if !dbg then Printf.printf "read_encoding_table: format 6\n";
read_format_6_encoding_table b;
| n -> raise (Pdf.PDFError "read_encoding_table: format %i not known\n") | n -> raise (Pdf.PDFError "read_encoding_table: format %i not known\n")
let read_loca_table indexToLocFormat numGlyphs b = let read_loca_table indexToLocFormat numGlyphs b =
@ -207,12 +195,6 @@ let calculate_flags symbolic italicangle =
let symbolic, nonsymbolic = if symbolic then 1, 0 else 0, 1 in let symbolic, nonsymbolic = if symbolic then 1, 0 else 0, 1 in
(italic lsl 6) lor (symbolic lsl 2) lor (nonsymbolic lsl 5) (italic lsl 6) lor (symbolic lsl 2) lor (nonsymbolic lsl 5)
let calculate_limits subset =
if subset = [] then (0, 255) else
extremes (sort compare subset)
let calculate_stemv () = 0
let read_hhea_table b = let read_hhea_table b =
discard_bytes b 34; discard_bytes b 34;
read_ushort b (* numOfLongHorMetrics *) read_ushort b (* numOfLongHorMetrics *)
@ -336,7 +318,7 @@ let calculate_widths unitsPerEm encoding firstchar lastchar subset cmapdata hmtx
if !dbg then Printf.printf "code %i --> " code; if !dbg then Printf.printf "code %i --> " code;
let code = unicode_codepoint_of_pdfcode encoding_table glyphlist_table code in let code = unicode_codepoint_of_pdfcode encoding_table glyphlist_table code in
if !dbg then Printf.printf "unicode %i --> " code; if !dbg then Printf.printf "unicode %i --> " code;
if subset <> [] && not (mem code subset) then 0 else if not (mem code subset) then 0 else
try try
let glyphnum = Hashtbl.find cmapdata code in let glyphnum = Hashtbl.find cmapdata code in
if !dbg then Printf.printf "glyph number %i --> " glyphnum; if !dbg then Printf.printf "glyph number %i --> " glyphnum;
@ -364,7 +346,6 @@ let calculate_width_higher unitsPerEm firstchar lastchar subset cmapdata hmtxdat
let calculate_maxwidth unitsPerEm hmtxdata = let calculate_maxwidth unitsPerEm hmtxdata =
pdf_unit unitsPerEm (hd (sort (fun a b -> compare b a) (Array.to_list hmtxdata))) pdf_unit unitsPerEm (hd (sort (fun a b -> compare b a) (Array.to_list hmtxdata)))
let fonumr = ref (-1) let fonumr = ref (-1)
let fonum () = fonumr += 1; !fonumr let fonum () = fonumr += 1; !fonumr
@ -373,7 +354,6 @@ let subset_font major minor tables indexToLocFormat subset encoding cmap loca mk
let tables = Array.of_list (sort (fun (_, _, o, _) (_, _, o', _) -> compare o o') tables) in let tables = Array.of_list (sort (fun (_, _, o, _) (_, _, o', _) -> compare o o') tables) in
let tablesout = ref [] in let tablesout = ref [] in
let cut = ref 0l in let cut = ref 0l in
if !dbg then Printf.printf "***Input:\n";
Array.iteri Array.iteri
(fun i (tag, checkSum, offset, ttlength) -> (fun i (tag, checkSum, offset, ttlength) ->
if !dbg then Printf.printf "tag = %li = %s, offset = %li\n" tag (string_of_tag tag) offset; if !dbg then Printf.printf "tag = %li = %s, offset = %li\n" tag (string_of_tag tag) offset;
@ -391,18 +371,16 @@ let subset_font major minor tables indexToLocFormat subset encoding cmap loca mk
(map (map
(fun (tag, checksum, offset, ttlength) -> (fun (tag, checksum, offset, ttlength) ->
let ttlength = let ttlength =
if string_of_tag tag = "glyf" && subset <> [] then if string_of_tag tag = "glyf" then
let bs = make_write_bitstream () in let bs = make_write_bitstream () in
let newlen = write_glyf_table subset cmap bs mk_b glyfoffset loca in let newlen = write_glyf_table subset cmap bs mk_b glyfoffset loca in
let paddedlen = i32ofi (bytes_size (bytes_of_write_bitstream bs)) in let paddedlen = i32ofi (bytes_size (bytes_of_write_bitstream bs)) in
if !dbg then Printf.printf "new glyf table length = %li\n" newlen;
glyf_table_size_reduction := i32sub (i32add ttlength (padding32 ttlength)) paddedlen; glyf_table_size_reduction := i32sub (i32add ttlength (padding32 ttlength)) paddedlen;
newlen newlen
else if string_of_tag tag = "cmap" && subset <> [] && encoding = Pdftext.ImplicitInFontFile then else if string_of_tag tag = "cmap" && encoding = Pdftext.ImplicitInFontFile then
let bs = make_write_bitstream () in let bs = make_write_bitstream () in
let newlen = write_cmap_table subset cmap bs in let newlen = write_cmap_table subset cmap bs in
let paddedlen = i32ofi (bytes_size (bytes_of_write_bitstream bs)) in let paddedlen = i32ofi (bytes_size (bytes_of_write_bitstream bs)) in
if !dbg then Printf.printf "new cmap table length = %li\n" newlen;
cmap_table_size_reduction := i32sub (i32add ttlength (padding32 ttlength)) paddedlen; cmap_table_size_reduction := i32sub (i32add ttlength (padding32 ttlength)) paddedlen;
newlen newlen
else else
@ -466,11 +444,11 @@ let subset_font major minor tables indexToLocFormat subset encoding cmap loca mk
Array.iter Array.iter
(fun (tag, _, _, _) -> (fun (tag, _, _, _) ->
if !dbg then Printf.printf "Writing %s table\n" (string_of_tag tag); if !dbg then Printf.printf "Writing %s table\n" (string_of_tag tag);
if string_of_tag tag = "loca" && subset <> [] then if string_of_tag tag = "loca" then
write_loca_table subset cmap indexToLocFormat bs loca write_loca_table subset cmap indexToLocFormat bs loca
else if string_of_tag tag = "glyf" && subset <> [] then else if string_of_tag tag = "glyf" then
ignore (write_glyf_table subset cmap bs mk_b glyfoffset loca) ignore (write_glyf_table subset cmap bs mk_b glyfoffset loca)
else if string_of_tag tag = "cmap" && subset <> [] && encoding = Pdftext.ImplicitInFontFile then else if string_of_tag tag = "cmap" && encoding = Pdftext.ImplicitInFontFile then
ignore (write_cmap_table subset cmap bs) ignore (write_cmap_table subset cmap bs)
else else
match findtag tag with match findtag tag with
@ -504,7 +482,6 @@ let parse ~subset data encoding =
let mk_b byte_offset = bitbytes_of_input (let i = input_of_bytes data in i.seek_in byte_offset; i) in 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 b = mk_b 0 in
let major, minor = read_fixed b in let major, minor = read_fixed b in
if !dbg then Printf.printf "Truetype font version %i.%i\n" major minor;
let numTables = read_ushort b in let numTables = read_ushort b in
let searchRange = read_ushort b in let searchRange = read_ushort b in
let entrySelector = read_ushort b in let entrySelector = read_ushort b in
@ -537,8 +514,6 @@ let parse ~subset data encoding =
discard_bytes b 6; discard_bytes b 6;
let indexToLocFormat = read_short b in let indexToLocFormat = read_short b in
let _ (*glyphDataFormat*) = read_short b in let _ (*glyphDataFormat*) = read_short b in
if !dbg then Printf.printf "head table: indexToLocFormat is %i\n" indexToLocFormat;
if !dbg then Printf.printf "box %i %i %i %i\n" minx miny maxx maxy;
let os2 = let os2 =
match keep (function (t, _, _, _) -> string_of_tag t = "OS/2") !tables with match keep (function (t, _, _, _) -> string_of_tag t = "OS/2") !tables with
| (_, _, o, l)::_ -> Some (o, l) | (_, _, o, l)::_ -> Some (o, l)
@ -604,7 +579,7 @@ let parse ~subset data encoding =
let subset_1, subsets_2 = find_main encoding subset in let subset_1, subsets_2 = find_main encoding subset in
let flags_1 = calculate_flags false italicangle in let flags_1 = calculate_flags false italicangle in
let flags_2 = calculate_flags true italicangle in let flags_2 = calculate_flags true italicangle in
let firstchar_1, lastchar_1 = calculate_limits subset_1 in let firstchar_1, lastchar_1 = extremes (sort compare subset_1) in
let firstchars_2, lastchars_2 = split (map (fun subset -> (33, length subset + 33 - 1)) subsets_2) in let firstchars_2, lastchars_2 = split (map (fun subset -> (33, length subset + 33 - 1)) subsets_2) in
let numOfLongHorMetrics = let numOfLongHorMetrics =
match keep (function (t, _, _, _) -> string_of_tag t = "hhea") !tables with match keep (function (t, _, _, _) -> string_of_tag t = "hhea") !tables with
@ -625,7 +600,7 @@ let parse ~subset data encoding =
firstchars_2 lastchars_2 subsets_2 firstchars_2 lastchars_2 subsets_2
in in
let maxwidth = calculate_maxwidth unitsPerEm hmtxdata in let maxwidth = calculate_maxwidth unitsPerEm hmtxdata in
let stemv = calculate_stemv () in let stemv = 0 in
let b = mk_b (i32toi locaoffset) in let b = mk_b (i32toi locaoffset) in
let loca = read_loca_table indexToLocFormat numGlyphs b in let loca = read_loca_table indexToLocFormat numGlyphs b in
let glyfoffset, glyflength = let glyfoffset, glyflength =
@ -676,7 +651,7 @@ let parse ~subset data encoding =
debug_t one; debug_t one;
write_font "one.ttf" one.subset_fontfile; write_font "one.ttf" one.subset_fontfile;
Printf.printf "\nHigher subset:\n"; Printf.printf "\nHigher subset:\n";
debug_t two; debug_t (hd twos);
write_font "two.ttf" (hd twos).subset_fontfile;*) write_font "two.ttf" (hd twos).subset_fontfile;*)
one::twos one::twos