-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcondense.py
78 lines (69 loc) · 2.48 KB
/
condense.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
71
72
73
74
75
76
77
78
def CondenseGlyph(glyph, scale, r):
glyph['advanceWidth'] = r(glyph['advanceWidth'] * scale)
rm = [ 'stemH', 'stemV', 'hintMasks', 'contourMasks', 'instructions' ]
for k in rm:
if k in glyph:
del glyph[k]
if 'contours' in glyph:
for contour in glyph['contours']:
for point in contour:
point['x'] = r(point['x'] * scale)
if 'references' in glyph:
for reference in glyph['references']:
reference['x'] = r(reference['x'] * scale)
def CondenseMarkToBase(subtable, scale, r):
for _, mark in subtable['marks'].items():
mark['x'] = r(mark['x'] * scale)
for _, base in subtable['bases'].items():
for _, klass in base.items():
klass['x'] = r(klass['x'] * scale)
def CondenseMarkToLig(subtable, scale, r):
for _, mark in subtable['marks'].items():
mark['x'] = r(mark['x'] * scale)
for _, base in subtable['bases'].items():
for component in base:
for _, klass in component.items():
klass['x'] = r(klass['x'] * scale)
def CondenseGposValue(entry, scale, r):
optional = lambda d, k: d[k] if k in d else 0
return {
k: r(optional(entry, k) * scale)
for k in [ 'dx', 'dWidth' ]
}
def CondenseGposSingle(subtable, scale, r):
for k, v in subtable.items():
subtable[k] = CondenseGposValue(v, scale, r)
def CondenseGposPair(subtable, scale, r):
for row in subtable['matrix']:
for j in range(len(row)):
if type(row[j]) in [ int, float ]:
# may be bad on `vkrn` table
row[j] = r(row[j] * scale)
else:
if 'first' in row[j]:
row[j]['first'] = CondenseGposValue(row[j]['first'], scale, r)
if 'second' in row[j]:
row[j]['second'] = CondenseGposValue(row[j]['second'], scale, r)
GposCondenser = {
'gpos_mark_to_base': CondenseMarkToBase,
'gpos_mark_to_mark': CondenseMarkToBase,
'gpos_mark_to_ligature': CondenseMarkToLig,
'gpos_single': CondenseGposSingle,
'gpos_pair': CondenseGposPair,
}
def Condense(font, scale, roundToInt = False):
r = round if roundToInt else lambda x: x
if scale == 1:
return
for _, g in font['glyf'].items():
CondenseGlyph(g, scale, r)
if 'OS_2' in font:
s = [ 'xAvgCharWidth', 'ySubscriptXSize', 'ySubscriptXOffset', 'ySupscriptXSize', 'ySupscriptXOffset' ]
for k in s:
font['OS_2'][k] = r(font['OS_2'][k] * scale)
if 'GPOS' in font:
for _, lookup in font['GPOS']['lookups'].items():
if lookup['type'] in GposCondenser:
scaler = GposCondenser[lookup['type']]
for subtable in lookup['subtables']:
scaler(subtable, scale, r)