Explore the table obtained from a TrueType font
Define the following macro in your TeX file:
function printtable (ind,tableau,prof) local k,l texio.write_nl(string.rep("...",prof) .. ind .. " -> {") prof=prof+1 for k,l in pairs(tableau) do if (type(l)=="table") then printtable(k,l,prof) else texio.write_nl(string.rep("...",prof) .. k .. " -> " .. tostring(l)) end end texio.write_nl(string.rep("...",prof-1) .. "}") end filename = kpse.find_file("#1","truetype fonts") ttffont = fontloader.to_table(fontloader.open(filename)) printtable("#1",ttffont,0)
and call it giving the name of the font you want to explore (the font must be in some directory known by kpse). Here is what you get for the "Gentium" font (strongly truncated, otherwise it would be too long for wiki):
( gentium -> { ...mark_class_cnt -> 0 ...glyphs -> { ......1 -> { .........boundingbox -> { ............1 -> 0 ............2 -> 0 ............3 -> 0 ............4 -> 0 .........} .........name -> .null .........unicodeenc -> 0 .........width -> 0 ......} ......2 -> { .........boundingbox -> { ............1 -> 0 ............2 -> 0 ............3 -> 0 ............4 -> 0 .........} .........name -> nonmarkingreturn .........unicodeenc -> 12 .........width -> 451 ......} ......3 -> { .........boundingbox -> { ............1 -> 0 ............2 -> 0 ............3 -> 0 ............4 -> 0 .........} .........name -> space .........unicodeenc -> 32 .........width -> 451 ......} ......4 -> { .........boundingbox -> { ............1 -> 154 ............2 -> -40 ............3 -> 391 ............4 -> 1480 .........} .........name -> exclam .........unicodeenc -> 33 .........width -> 557 ......} ......5 -> { .........boundingbox -> { ............1 -> 160 ............2 -> 813 ............3 -> 711 ............4 -> 1480 .........} .........name -> quotedbl .........unicodeenc -> 34 .........width -> 870 ......}
Explanation: the glyphs table is indexed by glyph indexes. Each glyph index maps to a bounding box, a potential (PostScript) name, a potential Unicode character, and to its width. Bounding box and width are given in font units.
......6 -> { .........boundingbox -> { ............1 -> 87 ............2 -> 127 ............3 -> 982 ............4 -> 1292 .........} .........name -> numbersign .........unicodeenc -> 35 .........width -> 961 ......} ......7 -> { .........boundingbox -> { ............1 -> 88 ............2 -> -174 ............3 -> 862 ............4 -> 1384 .........} .........name -> dollar .........unicodeenc -> 36 .........width -> 961 ......} ......8 -> { .........boundingbox -> { ............1 -> 76 ............2 -> -34 ............3 -> 1337 ............4 -> 1237 .........} .........name -> percent .........unicodeenc -> 37 .........width -> 1413 ......} ......9 -> { .........boundingbox -> { ............1 -> 80 ............2 -> -30 ............3 -> 1346 ............4 -> 1450 .........} .........name -> ampersand .........unicodeenc -> 38 .........width -> 1366 ......} ......10 -> { .........boundingbox -> { ............1 -> 160 ............2 -> 813 ............3 -> 352 ............4 -> 1480 .........} .........name -> quotesingle .........unicodeenc -> 39 .........width -> 512 ......} ......11 -> { .........boundingbox -> { ............1 -> 121 ............2 -> -315 ............3 -> 610 ............4 -> 1600 .........} .........name -> parenleft .........unicodeenc -> 40 .........possub -> { ............1 -> { ...............flags -> 0 ...............type -> substitution ...............subs -> { ..................variant -> parenright ...............} ...............script_lang_index -> 1 ...............tag -> rtla ............} .........} .........width -> 649 ......}
Here we have the special case of a glyph which has an attached OpenType transformation. In this case it is a (simple) substitution from the GSUB table. This substitution should happen when we are in the script+language combination indexed by number 1, and the OpenType which calls it is rtla, also known as �Right-to-left alternates�. The glyph �parenleft� is substituted by the glyph �parenright�.
......12 -> { .........boundingbox -> { ............1 -> 41 ............2 -> -315 ............3 -> 530 ............4 -> 1600 .........} .........name -> parenright .........unicodeenc -> 41 .........possub -> { ............1 -> { ...............flags -> 0 ...............type -> substitution ...............subs -> { ..................variant -> parenleft ...............} ...............script_lang_index -> 1 ...............tag -> rtla ............} .........} .........width -> 649 ......} ......13 -> { .........boundingbox -> { ............1 -> 70 ............2 -> 709 ............3 -> 846 ............4 -> 1561 .........} .........name -> asterisk .........unicodeenc -> 42 .........width -> 915 ......} ......14 -> { .........boundingbox -> { ............1 -> 61 ............2 -> 205 ............3 -> 778 ............4 -> 920 .........} .........name -> plus .........unicodeenc -> 43 .........width -> 840 ......} ......15 -> { .........boundingbox -> { ............1 -> 88 ............2 -> -305 ............3 -> 391 ............4 -> 230 .........} .........kerns -> { ............1 -> { ...............char -> quotedblright ...............off -> -220 ...............flags -> 0 ...............sli -> 0 ............} ............2 -> { ...............char -> quoteright ...............off -> -220 ...............flags -> 0 ...............sli -> 0 ............} .........} .........name -> comma .........unicodeenc -> 44 .........width -> 469 ......}
Here we have some kernings: the �comma� glyph gets kerned by -220 units when in front of �quoteright� or �quotedblright�.
......16 -> { .........boundingbox -> { ............1 -> 61 ............2 -> 455 ............3 -> 629 ............4 -> 569 .........} .........name -> hyphen .........unicodeenc -> 45 .........width -> 690 ......} ......17 -> { .........boundingbox -> { ............1 -> 131 ............2 -> -40 ............3 -> 369 ............4 -> 236 .........} .........kerns -> { ............1 -> { ...............char -> quotedblright ...............off -> -220 ...............flags -> 0 ...............sli -> 0 ............} ............2 -> { ...............char -> quoteright ...............off -> -220 ...............flags -> 0 ...............sli -> 0 ............} .........} .........name -> period .........unicodeenc -> 46 .........width -> 469 ......} ......18 -> { .........boundingbox -> { ............1 -> 49 ............2 -> -335 ............3 -> 909 ............4 -> 1600 .........} .........name -> slash .........unicodeenc -> 47 .........width -> 961 ......} ......19 -> { .........boundingbox -> { ............1 -> 76 ............2 -> -30 ............3 -> 885 ............4 -> 1235 .........} .........name -> zero .........unicodeenc -> 48 .........width -> 961 ......} ......20 -> { .........boundingbox -> { ............1 -> 139 ............2 -> 0 ............3 -> 840 ............4 -> 1245 .........} .........name -> one .........unicodeenc -> 49 .........width -> 961 ......} ......21 -> { .........boundingbox -> { ............1 -> 98 ............2 -> 0 ............3 -> 836 ............4 -> 1235 .........} .........name -> two .........unicodeenc -> 50 .........width -> 961 ......} ......22 -> { .........boundingbox -> { ............1 -> 68 ............2 -> -30 ............3 -> 825 ............4 -> 1235 .........} .........name -> three .........unicodeenc -> 51 .........width -> 961 ......} ......23 -> { .........boundingbox -> { ............1 -> 55 ............2 -> 0 ............3 -> 874 ............4 -> 1245 .........} .........name -> four .........unicodeenc -> 52 .........width -> 961 ......} ......24 -> { .........boundingbox -> { ............1 -> 78 ............2 -> -30 ............3 -> 836 ............4 -> 1223 .........} .........name -> five .........unicodeenc -> 53 .........width -> 961 ......} ......25 -> { .........boundingbox -> { ............1 -> 111 ............2 -> -30 ............3 -> 881 ............4 -> 1249 .........} .........name -> six .........unicodeenc -> 54 .........width -> 961 ......} ......26 -> { .........boundingbox -> { ............1 -> 104 ............2 -> -30 ............3 -> 885 ............4 -> 1204 .........} .........name -> seven .........unicodeenc -> 55 .........width -> 961 ......} ......27 -> { .........boundingbox -> { ............1 -> 94 ............2 -> -30 ............3 -> 864 ............4 -> 1235 .........} .........name -> eight .........unicodeenc -> 56 .........width -> 961 ......} ......28 -> { .........boundingbox -> { ............1 -> 100 ............2 -> -43 ............3 -> 870 ............4 -> 1235 .........} .........name -> nine .........unicodeenc -> 57 .........width -> 961 ......} ......29 -> { .........boundingbox -> { ............1 -> 131 ............2 -> -40 ............3 -> 369 ............4 -> 961 .........} .........name -> colon .........unicodeenc -> 58 .........width -> 469 ......} ......30 -> { .........boundingbox -> { ............1 -> 88 ............2 -> -305 ............3 -> 391 ............4 -> 961 .........} .........name -> semicolon .........unicodeenc -> 59 .........width -> 469 ......} ......31 -> { .........boundingbox -> { ............1 -> 61 ............2 -> 256 ............3 -> 838 ............4 -> 899 .........} .........name -> less .........unicodeenc -> 60 .........possub -> { ............1 -> { ...............flags -> 0 ...............type -> substitution ...............subs -> { ..................variant -> greater ...............} ...............script_lang_index -> 1 ...............tag -> rtla ............} .........} .........width -> 899 ......} ......32 -> { .........boundingbox -> { ............1 -> 61 ............2 -> 354 ............3 -> 838 ............4 -> 768 .........} .........name -> equal .........unicodeenc -> 61 .........width -> 899 ......} ......33 -> { .........boundingbox -> { ............1 -> 61 ............2 -> 256 ............3 -> 838 ............4 -> 899 .........} .........name -> greater .........unicodeenc -> 62 .........possub -> { ............1 -> { ...............flags -> 0 ...............type -> substitution ...............subs -> { ..................variant -> less ...............} ...............script_lang_index -> 1 ...............tag -> rtla ............} .........} .........width -> 899 ......} ......34 -> { .........boundingbox -> { ............1 -> 80 ............2 -> -40 ............3 -> 807 ............4 -> 1480 .........} .........name -> question .........unicodeenc -> 63 .........width -> 887 ......} ......35 -> { .........boundingbox -> { ............1 -> 70 ............2 -> -375 ............3 -> 1583 ............4 -> 1333 .........} .........name -> at .........unicodeenc -> 64 .........width -> 1653 ......} ......36 -> { .........boundingbox -> { ............1 -> 0 ............2 -> 0 ............3 -> 1198 ............4 -> 1317 .........} .........kerns -> { ............1 -> { ...............char -> quotedblright ...............off -> -200 ...............flags -> 0 ...............sli -> 0 ............} ............2 -> { ...............char -> quoteright ...............off -> -200 ...............flags -> 0 ...............sli -> 0 ............} ............3 -> { ...............char -> y ...............off -> -100 ...............flags -> 0 ...............sli -> 0 ............} ............4 -> { ...............char -> w ...............off -> -80 ...............flags -> 0 ...............sli -> 0 ............} ............5 -> { ...............char -> v ...............off -> -100 ...............flags -> 0 ...............sli -> 0 ............} ............6 -> { ...............char -> Y ...............off -> -180 ...............flags -> 0 ...............sli -> 0 ............} ............7 -> { ...............char -> W ...............off -> -120 ...............flags -> 0 ...............sli -> 0 ............} ............8 -> { ...............char -> V ...............off -> -160 ...............flags -> 0 ...............sli -> 0 ............} ............9 -> { ...............char -> U ...............off -> -80 ...............flags -> 0 ...............sli -> 0 ............} ............10 -> { ...............char -> T ...............off -> -100 ...............flags -> 0 ...............sli -> 0 ............} ............11 -> { ...............char -> Q ...............off -> -30 ...............flags -> 0 ...............sli -> 0 ............} ............12 -> { ...............char -> O ...............off -> -30 ...............flags -> 0 ...............sli -> 0 ............} ............13 -> { ...............char -> G ...............off -> -30 ...............flags -> 0 ...............sli -> 0 ............} ............14 -> { ...............char -> C ...............off -> -30 ...............flags -> 0 ...............sli -> 0 ............} .........} .........name -> A .........unicodeenc -> 65 .........width -> 1219 ......} ......37 -> { .........boundingbox -> { ............1 -> 41 ............2 -> -14 ............3 -> 1016 ............4 -> 1290 .........} .........name -> B .........unicodeenc -> 66 .........width -> 1126 ......} ......38 -> { .........boundingbox -> { ............1 -> 70 ............2 -> -30 ............3 -> 1018 ............4 -> 1290 .........} .........kerns -> { ............1 -> { ...............char -> A ...............off -> -60 ...............flags -> 0 ...............sli -> 0 ............} .........} .........name -> C .........unicodeenc -> 67 .........width -> 1098 ......} ......39 -> { .........boundingbox -> { ............1 -> 41 ............2 -> 0 ............3 -> 1124 ............4 -> 1290 .........} .........kerns -> { ............1 -> { ...............char -> Y ...............off -> -60 ...............flags -> 0 ...............sli -> 0 ............} ............2 -> { ...............char -> W ...............off -> -20 ...............flags -> 0 ...............sli -> 0 ............} ............3 -> { ...............char -> V ...............off -> 40 ...............flags -> 0 ...............sli -> 0 ............} ............4 -> { ...............char -> A ...............off -> -60 ...............flags -> 0 ...............sli -> 0 ............} .........} .........name -> D .........unicodeenc -> 68 .........width -> 1214 ......} another 35,850 lines of code ...} ...fontstyle_id -> 0 ...units_per_em -> 2048
2,048 units per em means that to obtain TeX quads we need to divide by that number.
...glyphcnt -> 1699 ...gasp_cnt -> 3 ...weight -> Book ...pfminfo -> { ......vlinegap -> 0 ......os2_subyoff -> 1200 ......hheadascent_add -> 1 ......os2_strikeypos -> 512 ......hhead_descent -> -565 ......os2_typolinegap -> 90 ......typodescent_add -> 1 ......weight -> 400 ......hhead_ascent -> 1759 ......os2_strikeysize -> 102 ......panose_set -> 1 ......os2_breakchar -> 0 ......pfmset -> 1 ......os2_typoascent -> -88 ......winascent_add -> 1 ......firstchar -> 32 ......os2_capheight -> 0 ......windescent_add -> 1 ......vheadset -> 0 ......os2_subxsize -> 856 ......os2_xheight -> 0 ......os2_supxoff -> 0 ......hheaddescent_add -> 1 ......os2_defaultchar -> 0 ......linegap -> 45 ......os2_family_class -> 0 ......os2_vendor -> SIL ......os2_supyoff -> 1200 ......os2_winascent -> 1759 ......os2_subysize -> 856 ......avgwidth -> 845 ......os2_subxoff -> 0 ......os2_supysize -> 856 ......os2_windescent -> 565 ......os2_typodescent -> -69 ......hheadset -> 1 ......fstype -> 0 ......os2_supxsize -> 856 ......lastchar -> 64260 ......panose -> { .........serifstyle -> Any .........armstyle -> Any .........contrast -> Medium .........familytype -> Text and Display .........proportion -> Modern .........strokevariation -> Any .........weight -> Book .........xheight -> Constant/Large .........midline -> Any .........letterform -> Normal/Contact ......} ......width -> 5 ......pfmfamily -> 17 ......subsuper_set -> 1 ......typoascent_add -> 1 ...} ...fullname -> GentiumAlt ...map -> { ......map -> { .........32 -> 3 .........33 -> 4 .........34 -> 5 .........35 -> 6 .........36 -> 7 .........37 -> 8 .........38 -> 9 .........39 -> 10 .........40 -> 11 another 1,679 lines .........65764 -> 1688 .........65765 -> 1689 .........65766 -> 1690 .........65767 -> 1691 .........65768 -> 1692 .........65769 -> 1693 .........65770 -> 1694 .........65771 -> 1695 .........65772 -> 1696 .........65773 -> 1697 .........65774 -> 1698 ......} ......enc -> { .........1 -> { ............has_2byte -> 1 ............char_max -> 0 ............only_1byte -> 0 ............is_unicodebmp -> 1 ............char_cnt -> 65536 ............high_page -> 0 ............has_1byte -> 0 ............low_page -> 0 ............builtin -> 1 ............enc_name -> UnicodeBmp ............hidden -> 1 .........} .........2 -> { ............has_2byte -> 0 ............char_max -> 0 ............only_1byte -> 0 ............is_original -> 1 ............char_cnt -> 0 ............high_page -> 0 ............has_1byte -> 0 ............low_page -> 0 ............builtin -> 1 ............enc_name -> Original ............hidden -> 1 .........} .........3 -> { ............has_2byte -> 0 ............char_max -> 0 ............only_1byte -> 0 ............char_cnt -> 0 ............is_custom -> 1 ............has_1byte -> 0 ............low_page -> 0 ............builtin -> 1 ............enc_name -> Custom ............high_page -> 0 ............hidden -> 1 .........} .........4 -> { ............has_2byte -> 0 ............char_max -> 0 ............only_1byte -> 1 ............char_cnt -> 256 ............high_page -> 0 ............has_1byte -> 1 ............low_page -> 0 ............builtin -> 1 ............enc_name -> TeX-Base-Encoding ............unicode -> { ...............1 -> 729 ...............2 -> 64257 ...............3 -> 64258 ...............4 -> 8260 ...............5 -> 733 ...............6 -> 321 ...............7 -> 322 ...............8 -> 731 another 238 lines ...............247 -> 247 ...............248 -> 248 ...............249 -> 249 ...............250 -> 250 ...............251 -> 251 ...............252 -> 252 ...............253 -> 253 ...............254 -> 254 ...............255 -> 255 ...............0 -> 0 ............} ............hidden -> 1 .........} ......} ......backmax -> 1699 ......enccount -> 65775 ......encmax -> 65775 ......backmap -> { .........1 -> 65537 .........2 -> 65538 .........3 -> 32 .........4 -> 33 .........5 -> 34 .........6 -> 35 .........7 -> 36 .........8 -> 37 .........9 -> 38 .........10 -> 39 .........11 -> 40 .........12 -> 41 .........13 -> 42 another 1,679 lines .........1693 -> 65769 .........1694 -> 65770 .........1695 -> 65771 .........1696 -> 65772 .........1697 -> 65773 .........1698 -> 65774 .........0 -> 65536 ......} ...} ...italicangle -> 0 ...strokedfont -> 0 ...cidinfo -> { ......supplement -> 0 ......version -> 0 ...} ...familyname -> GentiumAlt ...script_lang -> { ......1 -> { .........script -> latn .........langs -> { ............1 -> dflt .........} ......} ...}
The table script_lang contains scripts and languages. Here we have script latn (Latin) with default language.
...upos -> -48 ...version -> 1.01; 2003; initial SIL release ...glyphmax -> 1699 ...names -> { ......1 -> { .........lang -> English (US) .........names -> { ............designerurl -> http://www.sil.org/~gaultney ............venderurl -> http://www.sil.org/ ............compatfull -> GentiumAlt ............trademark -> Gentium is a trademark of SIL International. ............license -> This font is the property of SIL International. It is distributed as copyrighted freeware. You may use this software without any charge and may distribute it, as is, to others. Commercial distribution of this software is restricted without prior written permission. If you wish to distribute this software commercially, contact SIL for details on obtaining a license. You may not rent or lease the software, nor may you modify, adapt, translate, reverse engineer, decompile, or disassemb le the software. You may not make derivative fonts from this software. THE SOFTWARE AND RELATED FILES ARE PROVIDED "AS IS" AND WITHOUT WARRANTY OF ANY KIND. ............fullname -> GentiumAlt ............preffamilyname -> GentiumAlt ............designer -> J. Victor Gaultney ............copyright -> Copyright (c) SIL International 2003. All rights reserved. ............version -> Version 1.01; 2003; initial SIL release ............prefmodifiers -> Regular ............family -> GentiumAlt ............postscriptname -> GentiumAlt ............subfamily -> Regular ............uniqueid -> SIL: GentiumAlt: 2003 .........} ......} ...} ...gentags -> { ......tt_cur -> 0 ...} ...modificationtime -> 1063146346 ...fontname -> GentiumAlt ...changed -> 0 ...vertical_origin -> 0 ...table_version -> 0.1 ...hasvmetrics -> 0 ...creationtime -> 1032220800 ...order2 -> 1 ...head_optimized_for_cleartype -> 0 ...strokewidth -> 0 ...design_range_bottom -> 0 ...design_size -> 0 ...design_range_top -> 0 ...sli_cnt -> 1 ...macstyle -> -1 ...ttf_tables -> { ......1 -> { .........len -> 32 .........data -> .........maxlen -> 0 .........tag -> maxp ......} ...} ...copyright -> Copyright (c) SIL International 2003. All rights reserved. ...os2_version -> 1 ...gasp_version -> 0 ...uni_interp -> none ...uwidth -> 14 ...weight_width_slope_only -> 0 ...descent -> 410 ...ascent -> 1638 ...uniqueid -> 0 } )