字体研究

利用 Python 的 fonttools 包解析字体。

from fontTools.ttLib import TTFont
font = TTFont('/tmp/number_a.woff')

print(font.__dict__)
# {'verbose': None,
#  'quiet': None,
#  'lazy': None,
#  'recalcBBoxes': True,
#  'recalcTimestamp': True,
#  'tables': {'post': <'post' table at 7efc3dbacf28>,
#   'maxp': <'maxp' table at 7efc3e99a550>,
#   'cmap': <'cmap' table at 7efc3ec99518>},
#  'reader': <fontTools.ttLib.sfnt.SFNTReader at 0x7efc3daca5f8>,
#  'last_vid': 65534,
#  'reverseVIDDict': {},
#  'VIDDict': {},
#  'allowVID': False,
#  'ignoreDecompileErrors': False,
#  '_tableCache': None,
#  'sfntVersion': '\x00\x01\x00\x00',
#  'flavor': 'woff',
#  'flavorData': <fontTools.ttLib.sfnt.WOFFFlavorData at 0x7efc3eaf76d8>,
#  'glyphOrder': ['.notdef',
#   'uni0000',
#   'uni0001',
#   'space',
#   'u6F732',
#   'u72EF1',
#   'u7D3AE',
#   'uA8F2E',
#   'uAA86E',
#   'uC15F9',
#   'uC2E7A',
#   'uE7F11',
#   'uF8B41',
#   'uFC6A6']}

字体中包含:

  1. 字形
  2. 字形的顺序 GlyphOrder,这个有什么必要么?
  3. 字形与编码的对应关系 CMAP
cmap = ["{:04X}".format(ch): name for ch, name in x['cmap'].getBestCmap().items()]
print(cmap)
# {'0000': 'uni0000',
#  '0001': 'uni0001',
#  '0020': 'space',
#  '6F732': 'u6F732',
#  '72EF1': 'u72EF1',
#  '7D3AE': 'u7D3AE',
#  'A8F2E': 'uA8F2E',
#  'AA86E': 'uAA86E',
#  'C15F9': 'uC15F9',
#  'C2E7A': 'uC2E7A',
#  'E7F11': 'uE7F11',
#  'F8B41': 'uF8B41',
#  'FC6A6': 'uFC6A6'}

font 对象可以导出一个 XML 文件:

font.saveXML('/tmp/font.xml')

除了 cmap 之外,还可以看到一些类似 SVG 的 TTGlyph 节点,应该就是字体的矢量图。