-
Notifications
You must be signed in to change notification settings - Fork 1
/
font.py
70 lines (55 loc) · 2.26 KB
/
font.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
from fontTools.fontBuilder import FontBuilder
from fontTools.varLib.models import piecewiseLinearMap
async def createFontBuilder(rcjkfont, family_name, style, glyphs, glyphDataFormat=0):
upem = await rcjkfont.getUnitsPerEm()
glyphOrder = list(glyphs.keys())
metrics = {}
revCmap = await rcjkfont.getGlyphMap()
cmap = {}
for glyph in glyphs.values():
for unicode in revCmap[glyph.name]:
# Font has duplicate Unicodes unfortunately :(
# assert unicode not in cmap, (hex(unicode), glyphname, cmap[unicode])
cmap[unicode] = glyph.name
for glyphname in glyphOrder:
glyph = await rcjkfont.getGlyph(glyphname)
assert glyph.sources[0].name == "<default>"
assert glyph.sources[0].layerName == "foreground"
advance = glyph.layers["foreground"].glyph.xAdvance
metrics[glyphname] = (max(advance, 0), 0) # TODO lsb
if ".notdef" not in glyphOrder:
glyphOrder.insert(0, ".notdef")
metrics[".notdef"] = (upem, 0)
nameStrings = dict(
familyName=dict(en=family_name),
styleName=dict(en=style),
)
fb = FontBuilder(upem, isTTF=True)
fb.setupHead(
unitsPerEm=upem, glyphDataFormat=glyphDataFormat
) # created=rcjkfont.created, modified=rcjkfont.modified)
fb.setupNameTable(nameStrings)
fb.setupGlyphOrder(glyphOrder)
fb.setupCharacterMap(cmap)
fb.setupHorizontalMetrics(metrics)
ascent = int(upem * 0.8) # TODO
descent = -int(upem * 0.2) # TODO
fb.setupHorizontalHeader(ascent=ascent, descent=descent)
# fb.setupOS2(sTypoAscender=os2.sTypoAscender, usWinAscent=os2.usWinAscent, usWinDescent=os2.usWinDescent)
fb.setupPost(keepGlyphNames=False)
return fb
def fixLsb(fb):
metrics = fb.font["hmtx"].metrics
glyf = fb.font["glyf"]
for glyphname in glyf.keys():
v = getattr(glyf.glyphs[glyphname], "xMin", 0)
metrics[glyphname] = (metrics[glyphname][0], v)
def recalcSimpleGlyphBounds(fb):
glyf = fb.font["glyf"]
for glyphname in glyf.keys():
glyph = glyf.glyphs[glyphname]
if not hasattr(glyph, "data"):
glyph.recalcBounds(glyf)
def mapTuple(t, mapping):
mapping = dict(mapping)
return tuple(piecewiseLinearMap(v, mapping) for v in t)