www

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README

extract_tfms.py (3188B)


      1 #!/usr/bin/env python
      2 
      3 import collections
      4 import json
      5 import parse_tfm
      6 import subprocess
      7 import sys
      8 
      9 
     10 def find_font_path(font_name):
     11     try:
     12         font_path = subprocess.check_output(['kpsewhich', font_name])
     13     except OSError:
     14         raise RuntimeError("Couldn't find kpsewhich program, make sure you" +
     15                            " have TeX installed")
     16     except subprocess.CalledProcessError:
     17         raise RuntimeError("Couldn't find font metrics: '%s'" % font_name)
     18     return font_path.strip()
     19 
     20 
     21 def main():
     22     mapping = json.load(sys.stdin)
     23 
     24     fonts = [
     25         'cmbsy10.tfm',
     26         'cmbx10.tfm',
     27         'cmex10.tfm',
     28         'cmmi10.tfm',
     29         'cmmib10.tfm',
     30         'cmr10.tfm',
     31         'cmsy10.tfm',
     32         'cmti10.tfm',
     33         'msam10.tfm',
     34         'msbm10.tfm',
     35         'eufm10.tfm',
     36         'cmtt10.tfm',
     37         'rsfs10.tfm',
     38         'cmss10.tfm',
     39     ]
     40 
     41     # Extracted by running `\font\a=<font>` and then `\showthe\skewchar\a` in
     42     # TeX, where `<font>` is the name of the font listed here. The skewchar
     43     # will be printed out in the output. If it outputs `-1`, that means there
     44     # is no skewchar, so we use `None` here.
     45     font_skewchar = {
     46         'cmbsy10': None,
     47         'cmbx10': None,
     48         'cmex10': None,
     49         'cmmi10': 127,
     50         'cmmib10': None,
     51         'cmr10': None,
     52         'cmsy10': 48,
     53         'cmti10': None,
     54         'msam10': None,
     55         'msbm10': None,
     56         'eufm10': None,
     57         'cmtt10': None,
     58         'rsfs10': None,
     59         'cmss10': None,
     60     }
     61 
     62     font_name_to_tfm = {}
     63 
     64     for font_name in fonts:
     65         font_basename = font_name.split('.')[0]
     66         font_path = find_font_path(font_name)
     67         font_name_to_tfm[font_basename] = parse_tfm.read_tfm_file(font_path)
     68 
     69     families = collections.defaultdict(dict)
     70 
     71     for family, chars in mapping.iteritems():
     72         for char, char_data in chars.iteritems():
     73             char_num = int(char)
     74 
     75             font = char_data['font']
     76             tex_char_num = int(char_data['char'])
     77             yshift = float(char_data['yshift'])
     78 
     79             if family == "Script-Regular":
     80                 tfm_char = font_name_to_tfm[font].get_char_metrics(tex_char_num,
     81                                                                    fix_rsfs=True)
     82             else:
     83                 tfm_char = font_name_to_tfm[font].get_char_metrics(tex_char_num)
     84 
     85             height = round(tfm_char.height + yshift / 1000.0, 5)
     86             depth = round(tfm_char.depth - yshift / 1000.0, 5)
     87             italic = round(tfm_char.italic_correction, 5)
     88             width = round(tfm_char.width, 5)
     89 
     90             skewkern = 0.0
     91             if (font_skewchar[font] and
     92                     font_skewchar[font] in tfm_char.kern_table):
     93                 skewkern = round(
     94                     tfm_char.kern_table[font_skewchar[font]], 5)
     95 
     96             families[family][char_num] = {
     97                 'height': height,
     98                 'depth': depth,
     99                 'italic': italic,
    100                 'skew': skewkern,
    101                 'width': width
    102             }
    103 
    104     sys.stdout.write(
    105         json.dumps(families, separators=(',', ':'), sort_keys=True))
    106 
    107 if __name__ == '__main__':
    108     main()