scribble-math/metrics/extract_tfms.py
Kevin Barabash 67147b18ac Adds font metrics to support font commands.
This is part 1 of 3.  Rendering, screenshots, MathML, and unit tests will
follow in susbequent pull requests.
2015-07-10 21:50:04 -06:00

107 lines
3.0 KiB
Python
Executable File

#!/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=<font>` and then `\showthe\skewchar\a` in
# TeX, where `<font>` 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)
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,
}
sys.stdout.write(
json.dumps(families, separators=(',', ':'), sort_keys=True))
if __name__ == '__main__':
main()