#!/usr/bin/env python import collections import json import parse_tfm import subprocess import sys def find_font_path(font_name): try: font_path = subprocess.check_output(['kpsewhich', font_name]) except OSError: raise RuntimeError("Couldn't find kpsewhich program, make sure you" + " have TeX installed") except subprocess.CalledProcessError: raise RuntimeError("Couldn't find font metrics: '%s'" % font_name) return font_path.strip() def main(): mapping = json.load(sys.stdin) fonts = [ 'cmbsy10.tfm', 'cmbx10.tfm', 'cmex10.tfm', 'cmmi10.tfm', 'cmmib10.tfm', 'cmr10.tfm', 'cmsy10.tfm', 'cmti10.tfm', 'msam10.tfm', 'msbm10.tfm', 'eufm10.tfm', 'cmtt10.tfm', 'rsfs10.tfm', 'cmss10.tfm', ] # Extracted by running `\font\a=` and then `\showthe\skewchar\a` in # TeX, where `` is the name of the font listed here. The skewchar # will be printed out in the output. If it outputs `-1`, that means there # is no skewchar, so we use `None` here. font_skewchar = { 'cmbsy10': None, 'cmbx10': None, 'cmex10': None, 'cmmi10': 127, 'cmmib10': None, 'cmr10': None, 'cmsy10': 48, 'cmti10': None, 'msam10': None, 'msbm10': None, 'eufm10': None, 'cmtt10': None, 'rsfs10': None, 'cmss10': None, } font_name_to_tfm = {} for font_name in fonts: font_basename = font_name.split('.')[0] font_path = find_font_path(font_name) font_name_to_tfm[font_basename] = parse_tfm.read_tfm_file(font_path) families = collections.defaultdict(dict) for family, chars in mapping.iteritems(): for char, char_data in chars.iteritems(): char_num = int(char) font = char_data['font'] tex_char_num = int(char_data['char']) yshift = float(char_data['yshift']) if family == "Script-Regular": tfm_char = font_name_to_tfm[font].get_char_metrics(tex_char_num, fix_rsfs=True) else: tfm_char = font_name_to_tfm[font].get_char_metrics(tex_char_num) height = round(tfm_char.height + yshift / 1000.0, 5) depth = round(tfm_char.depth - yshift / 1000.0, 5) italic = round(tfm_char.italic_correction, 5) width = round(tfm_char.width, 5) skewkern = 0.0 if (font_skewchar[font] and font_skewchar[font] in tfm_char.kern_table): skewkern = round( tfm_char.kern_table[font_skewchar[font]], 5) families[family][char_num] = { 'height': height, 'depth': depth, 'italic': italic, 'skew': skewkern, 'width': width } sys.stdout.write( json.dumps(families, separators=(',', ':'), sort_keys=True)) if __name__ == '__main__': main()