Skip to content

Commit 6621ee6

Browse files
committed
add fontsetter
1 parent d2ec65d commit 6621ee6

File tree

1 file changed

+89
-0
lines changed

1 file changed

+89
-0
lines changed

Lib/gftools/fontsetter.py

+89
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
from fontTools.misc.cliTools import makeOutputFileName
2+
from fontTools.ttLib import TTFont
3+
import types
4+
import yaml
5+
import argparse
6+
7+
8+
def loads(string):
9+
"""
10+
name->setName: ["Hello world", 0, 3, 1, 0x409]
11+
OS/2->sTypoAscender: 1200
12+
-->
13+
{
14+
("name", "setName): ["Hello world", 0, 3, 1, 0x409],
15+
("OS/2", "sTypoAscender"): 1200,
16+
}
17+
"""
18+
config = yaml.safe_load(string)
19+
res = {}
20+
for k, v in config.items():
21+
path = k.split("->")
22+
res[tuple(path)] = v
23+
return res
24+
25+
26+
def load_config(fp):
27+
with open(fp, encoding="utf-8") as doc:
28+
return loads(doc.read())
29+
30+
31+
def hasmethod(obj, name):
32+
return hasattr(obj, name) and type(getattr(obj, name)) == types.MethodType
33+
34+
35+
def update_all(obj, config):
36+
for path, value in config.items():
37+
update(obj, path, value)
38+
39+
40+
def update(obj, path, val):
41+
if len(path) == 0:
42+
return
43+
key = path[0]
44+
45+
if len(path) == 1:
46+
if hasmethod(obj, key):
47+
getattr(obj, key)(*val)
48+
elif hasattr(obj, key):
49+
setattr(obj, key, val)
50+
else:
51+
obj[path[0]] = val
52+
return
53+
54+
if hasattr(obj, key):
55+
update(getattr(obj, key), path[1:])
56+
elif isinstance(obj, (list, dict, tuple, TTFont)):
57+
is_tuple = False
58+
# convert numeric keys if needed
59+
try:
60+
obj[key]
61+
except:
62+
key = str(key)
63+
obj[key]
64+
# convert tuples to lists and then reconvert back using backtracking
65+
if isinstance(obj[key], tuple):
66+
is_tuple = True
67+
obj[key] = list(obj[key])
68+
update(obj[key], path[1:], val)
69+
if is_tuple:
70+
obj[key] = tuple(obj[key])
71+
72+
73+
def main(args=None):
74+
parser = argparse.ArgumentParser()
75+
parser.add_argument("font", type=TTFont)
76+
parser.add_argument("config")
77+
parser.add_argument("-o", "--out", default=None)
78+
args = parser.parse_args(args)
79+
80+
config = load_config(args.config)
81+
update_all(args.font, config)
82+
83+
if not args.out:
84+
args.out = makeOutputFileName(args.font.reader.file.name)
85+
args.font.save(args.out)
86+
87+
88+
if __name__ == "__main__":
89+
main()

0 commit comments

Comments
 (0)