Switch from fontforge to fonttools

The dependencies of fonttools are much lighter than fontforge, and since all
we need are some metrics, fonttools is very much up to that task.

This addresses issue #288.
This commit is contained in:
Martin von Gagern 2015-07-09 17:33:50 +02:00
parent d26a67f220
commit b290d4ad76
3 changed files with 48 additions and 34 deletions

View File

@ -7,11 +7,11 @@ There are several requirements for generating the metrics used by KaTeX.
this by running `tex --version`, and seeing if it has a line that looks like this by running `tex --version`, and seeing if it has a line that looks like
> kpathsea version 6.2.0 > kpathsea version 6.2.0
- You need the JSON module for perl. You can install this either from CPAN or with - You need the JSON module for perl. You can install this either from CPAN
your package manager. (possibly using the `cpan` command line tool) or with your package manager.
- You need the python fontforge module. This is probably either installed with - You need the python module fonttools. You can install this either from PyPi
fontforge or can be installed from your package manager. (using `easy_install` or `pip`) or with your package manager.
Once you have these things, run Once you have these things, run

View File

@ -1,6 +1,6 @@
#!/usr/bin/env python #!/usr/bin/env python
import fontforge from fontTools.ttLib import TTFont
import sys import sys
import json import json
@ -60,33 +60,47 @@ def main():
start_json = json.load(sys.stdin) start_json = json.load(sys.stdin)
for font, chars in metrics_to_extract.iteritems(): for font, chars in metrics_to_extract.iteritems():
fontInfo = fontforge.open("../static/fonts/KaTeX_" + font + ".ttf") fontInfo = TTFont("../static/fonts/KaTeX_" + font + ".ttf")
glyf = fontInfo["glyf"]
unitsPerEm = float(fontInfo["head"].unitsPerEm)
for glyph in fontInfo.glyphs(): # We keep ALL Unicode cmaps, not just fontInfo["cmap"].getcmap(3, 1).
try: # This is playing it extra safe, since it reports inconsistencies.
char = unichr(glyph.unicode) # Platform 0 is Unicode, platform 3 is Windows. For platform 3,
except ValueError: # encoding 1 is UCS-2 and encoding 10 is UCS-4.
cmap = [t.cmap for t in fontInfo["cmap"].tables
if (t.platformID == 0)
or (t.platformID == 3 and t.platEncID in (1, 10))]
for char, base_char in chars.iteritems():
code = ord(char)
names = set(t.get(code) for t in cmap)
if not names:
sys.stderr.write(
"Codepoint {} of font {} maps to no name\n"
.format(code, font))
continue continue
if len(names) != 1:
sys.stderr.write(
"Codepoint {} of font {} maps to multiple names: {}\n"
.format(code, font, ", ".join(sorted(names))))
continue
name = names.pop()
if char in chars: height = depth = italic = skew = 0
_, depth, _, height = glyph.boundingBox() glyph = glyf[name]
if glyph.numberOfContours:
depth = -depth height = glyph.yMax
depth = -glyph.yMin
base_char = chars[char]
if base_char: if base_char:
base_char_str = str(ord(base_char)) base_char_str = str(ord(base_char))
base_metrics = start_json[font][base_char_str] base_metrics = start_json[font][base_char_str]
italic = base_metrics["italic"] italic = base_metrics["italic"]
skew = base_metrics["skew"] skew = base_metrics["skew"]
else:
italic = 0
skew = 0
start_json[font][str(ord(char))] = { start_json[font][str(code)] = {
"height": height / fontInfo.em, "height": height / unitsPerEm,
"depth": depth / fontInfo.em, "depth": depth / unitsPerEm,
"italic": italic, "italic": italic,
"skew": skew, "skew": skew,
} }

View File

@ -632,7 +632,7 @@
"8463": {"depth": 0.0, "height": 0.68889, "italic": 0.0, "skew": 0.0} "8463": {"depth": 0.0, "height": 0.68889, "italic": 0.0, "skew": 0.0}
}, },
"Main-Regular": { "Main-Regular": {
"32": {"depth": -0.0, "height": 0.0, "italic": 0, "skew": 0}, "32": {"depth": 0.0, "height": 0.0, "italic": 0, "skew": 0},
"33": {"depth": 0.0, "height": 0.69444, "italic": 0.0, "skew": 0.0}, "33": {"depth": 0.0, "height": 0.69444, "italic": 0.0, "skew": 0.0},
"34": {"depth": 0.0, "height": 0.69444, "italic": 0.0, "skew": 0.0}, "34": {"depth": 0.0, "height": 0.69444, "italic": 0.0, "skew": 0.0},
"35": {"depth": 0.19444, "height": 0.69444, "italic": 0.0, "skew": 0.0}, "35": {"depth": 0.19444, "height": 0.69444, "italic": 0.0, "skew": 0.0},
@ -727,7 +727,7 @@
"124": {"depth": 0.25, "height": 0.75, "italic": 0.0, "skew": 0.0}, "124": {"depth": 0.25, "height": 0.75, "italic": 0.0, "skew": 0.0},
"125": {"depth": 0.25, "height": 0.75, "italic": 0.0, "skew": 0.0}, "125": {"depth": 0.25, "height": 0.75, "italic": 0.0, "skew": 0.0},
"126": {"depth": 0.35, "height": 0.31786, "italic": 0.0, "skew": 0.0}, "126": {"depth": 0.35, "height": 0.31786, "italic": 0.0, "skew": 0.0},
"160": {"depth": -0.0, "height": 0.0, "italic": 0, "skew": 0}, "160": {"depth": 0.0, "height": 0.0, "italic": 0, "skew": 0},
"168": {"depth": 0.0, "height": 0.66786, "italic": 0.0, "skew": 0.0}, "168": {"depth": 0.0, "height": 0.66786, "italic": 0.0, "skew": 0.0},
"172": {"depth": 0.0, "height": 0.43056, "italic": 0.0, "skew": 0.0}, "172": {"depth": 0.0, "height": 0.43056, "italic": 0.0, "skew": 0.0},
"175": {"depth": 0.0, "height": 0.56778, "italic": 0.0, "skew": 0.0}, "175": {"depth": 0.0, "height": 0.56778, "italic": 0.0, "skew": 0.0},
@ -778,7 +778,7 @@
"8221": {"depth": 0.0, "height": 0.69444, "italic": 0.0, "skew": 0.0}, "8221": {"depth": 0.0, "height": 0.69444, "italic": 0.0, "skew": 0.0},
"8224": {"depth": 0.19444, "height": 0.69444, "italic": 0.0, "skew": 0.0}, "8224": {"depth": 0.19444, "height": 0.69444, "italic": 0.0, "skew": 0.0},
"8225": {"depth": 0.19444, "height": 0.69444, "italic": 0.0, "skew": 0.0}, "8225": {"depth": 0.19444, "height": 0.69444, "italic": 0.0, "skew": 0.0},
"8230": {"depth": -0.0, "height": 0.12, "italic": 0, "skew": 0}, "8230": {"depth": 0.0, "height": 0.12, "italic": 0, "skew": 0},
"8242": {"depth": 0.0, "height": 0.55556, "italic": 0.0, "skew": 0.0}, "8242": {"depth": 0.0, "height": 0.55556, "italic": 0.0, "skew": 0.0},
"8407": {"depth": 0.0, "height": 0.71444, "italic": 0.15382, "skew": 0.0}, "8407": {"depth": 0.0, "height": 0.71444, "italic": 0.15382, "skew": 0.0},
"8463": {"depth": 0.0, "height": 0.68889, "italic": 0.0, "skew": 0.0}, "8463": {"depth": 0.0, "height": 0.68889, "italic": 0.0, "skew": 0.0},