Removed the subset=[] stuff
This commit is contained in:
parent
f4f83ceca7
commit
66f964bba3
381
cpdftruetype.ml
381
cpdftruetype.ml
|
@ -4,8 +4,8 @@ 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 *)
|
||||||
let dbg = ref false
|
let dbg = ref false
|
||||||
|
@ -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,181 +482,178 @@ 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
|
let rangeShift = read_ushort b in
|
||||||
let rangeShift = read_ushort b in
|
if !dbg then Printf.printf "numTables = %i, searchRange = %i, entrySelector = %i, rangeShift = %i\n"
|
||||||
if !dbg then Printf.printf "numTables = %i, searchRange = %i, entrySelector = %i, rangeShift = %i\n"
|
numTables searchRange entrySelector rangeShift;
|
||||||
numTables searchRange entrySelector rangeShift;
|
let tables = ref [] in
|
||||||
let tables = ref [] in
|
for x = 1 to numTables do
|
||||||
for x = 1 to numTables do
|
let tag = read_ulong b in
|
||||||
let tag = read_ulong b in
|
let checkSum = read_ulong b in
|
||||||
let checkSum = read_ulong b in
|
let offset = read_ulong b in
|
||||||
let offset = read_ulong b in
|
let ttlength = read_ulong b in
|
||||||
let ttlength = read_ulong b in
|
if !dbg then Printf.printf "tag = %li = %s, checkSum = %li, offset = %li, ttlength = %li\n"
|
||||||
if !dbg then Printf.printf "tag = %li = %s, checkSum = %li, offset = %li, ttlength = %li\n"
|
tag (string_of_tag tag) checkSum offset ttlength;
|
||||||
tag (string_of_tag tag) checkSum offset ttlength;
|
tables =| (tag, checkSum, offset, ttlength);
|
||||||
tables =| (tag, checkSum, offset, ttlength);
|
done;
|
||||||
done;
|
let headoffset, headlength =
|
||||||
let headoffset, headlength =
|
match keep (function (t, _, _, _) -> string_of_tag t = "head") !tables with
|
||||||
match keep (function (t, _, _, _) -> string_of_tag t = "head") !tables with
|
| (_, _, o, l)::_ -> o, l
|
||||||
| (_, _, o, l)::_ -> o, l
|
| [] -> raise (Pdf.PDFError "No maxp table found in TrueType font")
|
||||||
| [] -> raise (Pdf.PDFError "No maxp table found in TrueType font")
|
in
|
||||||
in
|
let b = mk_b (i32toi headoffset) in
|
||||||
let b = mk_b (i32toi headoffset) in
|
discard_bytes b 18;
|
||||||
discard_bytes b 18;
|
let unitsPerEm = read_ushort b in
|
||||||
let unitsPerEm = read_ushort b in
|
discard_bytes b 16;
|
||||||
discard_bytes b 16;
|
let minx = pdf_unit unitsPerEm (read_short b) in
|
||||||
let minx = pdf_unit unitsPerEm (read_short b) in
|
let miny = pdf_unit unitsPerEm (read_short b) in
|
||||||
let miny = pdf_unit unitsPerEm (read_short b) in
|
let maxx = pdf_unit unitsPerEm (read_short b) in
|
||||||
let maxx = pdf_unit unitsPerEm (read_short b) in
|
let maxy = pdf_unit unitsPerEm (read_short b) in
|
||||||
let maxy = pdf_unit unitsPerEm (read_short b) in
|
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
|
let os2 =
|
||||||
if !dbg then Printf.printf "head table: indexToLocFormat is %i\n" indexToLocFormat;
|
match keep (function (t, _, _, _) -> string_of_tag t = "OS/2") !tables with
|
||||||
if !dbg then Printf.printf "box %i %i %i %i\n" minx miny maxx maxy;
|
| (_, _, o, l)::_ -> Some (o, l)
|
||||||
let os2 =
|
| [] -> None
|
||||||
match keep (function (t, _, _, _) -> string_of_tag t = "OS/2") !tables with
|
in
|
||||||
| (_, _, o, l)::_ -> Some (o, l)
|
let ascent, descent, capheight, xheight, avgwidth =
|
||||||
| [] -> None
|
match os2 with
|
||||||
in
|
| None -> raise (Pdf.PDFError "No os/2 table found in truetype font")
|
||||||
let ascent, descent, capheight, xheight, avgwidth =
|
| Some (o, l) -> let b = mk_b (i32toi o) in read_os2_table unitsPerEm b (i32toi l)
|
||||||
match os2 with
|
in
|
||||||
| None -> raise (Pdf.PDFError "No os/2 table found in truetype font")
|
let italicangle =
|
||||||
| Some (o, l) -> let b = mk_b (i32toi o) in read_os2_table unitsPerEm b (i32toi l)
|
match keep (function (t, _, _, _) -> string_of_tag t = "post") !tables with
|
||||||
in
|
| (_, _, o, _)::_ -> read_post_table (mk_b (i32toi o))
|
||||||
let italicangle =
|
|
||||||
match keep (function (t, _, _, _) -> string_of_tag t = "post") !tables with
|
|
||||||
| (_, _, o, _)::_ -> read_post_table (mk_b (i32toi o))
|
|
||||||
| _ -> 0
|
|
||||||
in
|
|
||||||
if !dbg then
|
|
||||||
Printf.printf "ascent %i descent %i capheight %i xheight %i avgwidth %i\n"
|
|
||||||
ascent descent capheight xheight avgwidth;
|
|
||||||
let cmap =
|
|
||||||
match keep (function (t, _, _, _) -> string_of_tag t = "cmap") !tables with
|
|
||||||
| (_, _, o, l)::_ -> Some (o, l)
|
|
||||||
| [] -> None
|
|
||||||
in
|
|
||||||
let glyphcodes = ref (null_hash ()) in
|
|
||||||
begin match cmap with
|
|
||||||
| None ->
|
|
||||||
for x = 0 to 255 do Hashtbl.add !glyphcodes x x done
|
|
||||||
| Some (cmapoffset, cmaplength) ->
|
|
||||||
let b = mk_b (i32toi cmapoffset) in
|
|
||||||
let cmap_version = read_ushort b in
|
|
||||||
let num_encoding_tables = read_ushort b in
|
|
||||||
if !dbg then Printf.printf "cmap version %i. There are %i encoding tables\n"
|
|
||||||
cmap_version num_encoding_tables;
|
|
||||||
for x = 1 to num_encoding_tables do
|
|
||||||
let platform_id = read_ushort b in
|
|
||||||
let encoding_id = read_ushort b in
|
|
||||||
let subtable_offset = read_ulong b in
|
|
||||||
if !dbg then Printf.printf "subtable %i. platform_id = %i, encoding_id = %i, subtable_offset = %li\n"
|
|
||||||
x platform_id encoding_id subtable_offset;
|
|
||||||
let b = mk_b (i32toi cmapoffset + i32toi subtable_offset) in
|
|
||||||
let fmt = read_ushort b in
|
|
||||||
let lngth = read_ushort b in
|
|
||||||
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
|
|
||||||
Hashtbl.iter (Hashtbl.add !glyphcodes) got_glyphcodes
|
|
||||||
done;
|
|
||||||
end;
|
|
||||||
let maxpoffset, maxplength =
|
|
||||||
match keep (function (t, _, _, _) -> string_of_tag t = "maxp") !tables with
|
|
||||||
| (_, _, o, l)::_ -> o, l
|
|
||||||
| [] -> raise (Pdf.PDFError "No maxp table found in TrueType font")
|
|
||||||
in
|
|
||||||
let b = mk_b (i32toi maxpoffset) in
|
|
||||||
let mmajor, mminor = read_fixed b in
|
|
||||||
let numGlyphs = read_ushort b in
|
|
||||||
if !dbg then Printf.printf "maxp table version %i.%i: This font has %i glyphs\n" mmajor mminor numGlyphs;
|
|
||||||
let locaoffset, localength =
|
|
||||||
match keep (function (t, _, _, _) -> string_of_tag t = "loca") !tables with
|
|
||||||
| (_, _, o, l)::_ -> o, l
|
|
||||||
| [] -> raise (Pdf.PDFError "No loca table found in TrueType font")
|
|
||||||
in
|
|
||||||
let subset_1, subsets_2 = find_main encoding subset in
|
|
||||||
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
|
|
||||||
let firstchars_2, lastchars_2 = split (map (fun subset -> (33, length subset + 33 - 1)) subsets_2) in
|
|
||||||
let numOfLongHorMetrics =
|
|
||||||
match keep (function (t, _, _, _) -> string_of_tag t = "hhea") !tables with
|
|
||||||
| (_, _, o, l)::_ -> let b = mk_b (i32toi o) in read_hhea_table b
|
|
||||||
| _ -> 0
|
| _ -> 0
|
||||||
in
|
in
|
||||||
let hmtxdata =
|
if !dbg then
|
||||||
match keep (function (t, _, _, _) -> string_of_tag t = "hmtx") !tables with
|
Printf.printf "ascent %i descent %i capheight %i xheight %i avgwidth %i\n"
|
||||||
| (_, _, o, _)::_ -> read_hmtx_table numOfLongHorMetrics (mk_b (i32toi o))
|
ascent descent capheight xheight avgwidth;
|
||||||
| [] -> raise (Pdf.PDFError "No hmtx table found in TrueType font")
|
let cmap =
|
||||||
|
match keep (function (t, _, _, _) -> string_of_tag t = "cmap") !tables with
|
||||||
|
| (_, _, o, l)::_ -> Some (o, l)
|
||||||
|
| [] -> None
|
||||||
in
|
in
|
||||||
let widths_1 =
|
let glyphcodes = ref (null_hash ()) in
|
||||||
calculate_widths unitsPerEm encoding firstchar_1 lastchar_1 subset_1 !glyphcodes hmtxdata
|
begin match cmap with
|
||||||
in
|
| None ->
|
||||||
let widths_2 =
|
for x = 0 to 255 do Hashtbl.add !glyphcodes x x done
|
||||||
map3
|
| Some (cmapoffset, cmaplength) ->
|
||||||
(fun f l s -> calculate_width_higher unitsPerEm f l s !glyphcodes hmtxdata)
|
let b = mk_b (i32toi cmapoffset) in
|
||||||
firstchars_2 lastchars_2 subsets_2
|
let cmap_version = read_ushort b in
|
||||||
in
|
let num_encoding_tables = read_ushort b in
|
||||||
let maxwidth = calculate_maxwidth unitsPerEm hmtxdata in
|
if !dbg then Printf.printf "cmap version %i. There are %i encoding tables\n"
|
||||||
let stemv = calculate_stemv () in
|
cmap_version num_encoding_tables;
|
||||||
let b = mk_b (i32toi locaoffset) in
|
for x = 1 to num_encoding_tables do
|
||||||
let loca = read_loca_table indexToLocFormat numGlyphs b in
|
let platform_id = read_ushort b in
|
||||||
let glyfoffset, glyflength =
|
let encoding_id = read_ushort b in
|
||||||
match keep (function (t, _, _, _) -> string_of_tag t = "glyf") !tables with
|
let subtable_offset = read_ulong b in
|
||||||
| (_, _, o, l)::_ -> o, l
|
if !dbg then Printf.printf "subtable %i. platform_id = %i, encoding_id = %i, subtable_offset = %li\n"
|
||||||
| [] -> raise (Pdf.PDFError "No glyf table found in TrueType font")
|
x platform_id encoding_id subtable_offset;
|
||||||
in
|
let b = mk_b (i32toi cmapoffset + i32toi subtable_offset) in
|
||||||
let main_subset =
|
let fmt = read_ushort b in
|
||||||
subset_font major minor !tables indexToLocFormat subset_1
|
let lngth = read_ushort b in
|
||||||
encoding !glyphcodes loca mk_b glyfoffset data
|
let version = read_ushort b in
|
||||||
in
|
if !dbg then Printf.printf "subtable has format %i, length %i, version %i\n" fmt lngth version;
|
||||||
let seconds_subsets =
|
let got_glyphcodes = read_encoding_table fmt lngth version b in
|
||||||
map
|
Hashtbl.iter (Hashtbl.add !glyphcodes) got_glyphcodes
|
||||||
(fun subset ->
|
done;
|
||||||
subset_font
|
end;
|
||||||
major minor !tables indexToLocFormat subset Pdftext.ImplicitInFontFile
|
let maxpoffset, maxplength =
|
||||||
!glyphcodes loca mk_b glyfoffset data)
|
match keep (function (t, _, _, _) -> string_of_tag t = "maxp") !tables with
|
||||||
subsets_2
|
| (_, _, o, l)::_ -> o, l
|
||||||
in
|
| [] -> raise (Pdf.PDFError "No maxp table found in TrueType font")
|
||||||
let seconds_tounicodes =
|
in
|
||||||
map
|
let b = mk_b (i32toi maxpoffset) in
|
||||||
(fun subset ->
|
let mmajor, mminor = read_fixed b in
|
||||||
if subset = [] then None else
|
let numGlyphs = read_ushort b in
|
||||||
let h = null_hash () in
|
if !dbg then Printf.printf "maxp table version %i.%i: This font has %i glyphs\n" mmajor mminor numGlyphs;
|
||||||
List.iter2
|
let locaoffset, localength =
|
||||||
(fun n u ->
|
match keep (function (t, _, _, _) -> string_of_tag t = "loca") !tables with
|
||||||
let s = implode (tl (tl (explode (Pdftext.utf16be_of_codepoints [u])))) in
|
| (_, _, o, l)::_ -> o, l
|
||||||
Hashtbl.add h n s)
|
| [] -> raise (Pdf.PDFError "No loca table found in TrueType font")
|
||||||
(map (( + ) 33) (indx0 subset))
|
in
|
||||||
subset;
|
let subset_1, subsets_2 = find_main encoding subset in
|
||||||
Some h)
|
let flags_1 = calculate_flags false italicangle in
|
||||||
|
let flags_2 = calculate_flags true italicangle 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 numOfLongHorMetrics =
|
||||||
|
match keep (function (t, _, _, _) -> string_of_tag t = "hhea") !tables with
|
||||||
|
| (_, _, o, l)::_ -> let b = mk_b (i32toi o) in read_hhea_table b
|
||||||
|
| _ -> 0
|
||||||
|
in
|
||||||
|
let hmtxdata =
|
||||||
|
match keep (function (t, _, _, _) -> string_of_tag t = "hmtx") !tables with
|
||||||
|
| (_, _, o, _)::_ -> read_hmtx_table numOfLongHorMetrics (mk_b (i32toi o))
|
||||||
|
| [] -> raise (Pdf.PDFError "No hmtx table found in TrueType font")
|
||||||
|
in
|
||||||
|
let widths_1 =
|
||||||
|
calculate_widths unitsPerEm encoding firstchar_1 lastchar_1 subset_1 !glyphcodes hmtxdata
|
||||||
|
in
|
||||||
|
let widths_2 =
|
||||||
|
map3
|
||||||
|
(fun f l s -> calculate_width_higher unitsPerEm f l s !glyphcodes hmtxdata)
|
||||||
|
firstchars_2 lastchars_2 subsets_2
|
||||||
|
in
|
||||||
|
let maxwidth = calculate_maxwidth unitsPerEm hmtxdata in
|
||||||
|
let stemv = 0 in
|
||||||
|
let b = mk_b (i32toi locaoffset) in
|
||||||
|
let loca = read_loca_table indexToLocFormat numGlyphs b in
|
||||||
|
let glyfoffset, glyflength =
|
||||||
|
match keep (function (t, _, _, _) -> string_of_tag t = "glyf") !tables with
|
||||||
|
| (_, _, o, l)::_ -> o, l
|
||||||
|
| [] -> raise (Pdf.PDFError "No glyf table found in TrueType font")
|
||||||
|
in
|
||||||
|
let main_subset =
|
||||||
|
subset_font major minor !tables indexToLocFormat subset_1
|
||||||
|
encoding !glyphcodes loca mk_b glyfoffset data
|
||||||
|
in
|
||||||
|
let seconds_subsets =
|
||||||
|
map
|
||||||
|
(fun subset ->
|
||||||
|
subset_font
|
||||||
|
major minor !tables indexToLocFormat subset Pdftext.ImplicitInFontFile
|
||||||
|
!glyphcodes loca mk_b glyfoffset data)
|
||||||
subsets_2
|
subsets_2
|
||||||
in
|
in
|
||||||
let one =
|
let seconds_tounicodes =
|
||||||
{flags = flags_1; minx; miny; maxx; maxy; italicangle; ascent; descent;
|
map
|
||||||
capheight; stemv; xheight; avgwidth; maxwidth; firstchar = firstchar_1; lastchar = lastchar_1;
|
(fun subset ->
|
||||||
widths = widths_1; subset_fontfile = main_subset; subset = subset_1; tounicode = None}
|
if subset = [] then None else
|
||||||
in
|
let h = null_hash () in
|
||||||
let twos =
|
List.iter2
|
||||||
map6
|
(fun n u ->
|
||||||
(fun firstchar lastchar widths subset_fontfile subset tounicode ->
|
let s = implode (tl (tl (explode (Pdftext.utf16be_of_codepoints [u])))) in
|
||||||
{flags = flags_2; minx; miny; maxx; maxy; italicangle; ascent; descent;
|
Hashtbl.add h n s)
|
||||||
capheight; stemv; xheight; avgwidth; maxwidth; firstchar; lastchar;
|
(map (( + ) 33) (indx0 subset))
|
||||||
widths; subset_fontfile; subset; tounicode})
|
subset;
|
||||||
firstchars_2 lastchars_2 widths_2 seconds_subsets subsets_2 seconds_tounicodes
|
Some h)
|
||||||
in
|
subsets_2
|
||||||
(*Printf.printf "\nMain subset:\n";
|
in
|
||||||
debug_t one;
|
let one =
|
||||||
write_font "one.ttf" one.subset_fontfile;
|
{flags = flags_1; minx; miny; maxx; maxy; italicangle; ascent; descent;
|
||||||
Printf.printf "\nHigher subset:\n";
|
capheight; stemv; xheight; avgwidth; maxwidth; firstchar = firstchar_1; lastchar = lastchar_1;
|
||||||
debug_t two;
|
widths = widths_1; subset_fontfile = main_subset; subset = subset_1; tounicode = None}
|
||||||
write_font "two.ttf" (hd twos).subset_fontfile;*)
|
in
|
||||||
one::twos
|
let twos =
|
||||||
|
map6
|
||||||
|
(fun firstchar lastchar widths subset_fontfile subset tounicode ->
|
||||||
|
{flags = flags_2; minx; miny; maxx; maxy; italicangle; ascent; descent;
|
||||||
|
capheight; stemv; xheight; avgwidth; maxwidth; firstchar; lastchar;
|
||||||
|
widths; subset_fontfile; subset; tounicode})
|
||||||
|
firstchars_2 lastchars_2 widths_2 seconds_subsets subsets_2 seconds_tounicodes
|
||||||
|
in
|
||||||
|
(*Printf.printf "\nMain subset:\n";
|
||||||
|
debug_t one;
|
||||||
|
write_font "one.ttf" one.subset_fontfile;
|
||||||
|
Printf.printf "\nHigher subset:\n";
|
||||||
|
debug_t (hd twos);
|
||||||
|
write_font "two.ttf" (hd twos).subset_fontfile;*)
|
||||||
|
one::twos
|
||||||
|
|
||||||
let parse ~subset data encoding =
|
let parse ~subset data encoding =
|
||||||
try parse ~subset data encoding with
|
try parse ~subset data encoding with
|
||||||
|
|
Loading…
Reference in New Issue