-
Notifications
You must be signed in to change notification settings - Fork 11
/
Copy pathfontname.py
99 lines (82 loc) · 3.59 KB
/
fontname.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
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
import sys
import os
from fontTools import ttLib
def main(argv):
# command argument tests
if len(argv) < 2:
exit_with_error_msg(f"""
[fontname.py] ERROR: you did not include enough arguments to the script."
Usage: python3 fontname.py [NEW FAMILY NAME] [FONT PATH 1] <FONT PATH 2 ...>"
""")
try:
new_family_name = str(argv[0]) # the first argument is the new typeface name
except Exception as e:
exit_with_error_msg(f"[fontname.py] ERROR: unable to convert argument 1 to string.")
# all remaining arguments on command line are file paths to fonts
font_path_list = argv[1:]
# iterate through all paths provided on command line and rename to `new_font_name` defined by user
for font_path in font_path_list:
if not file_exists(font_path):
exit_with_error_msg(f"[fontname.py] ERROR: the path '{font_path}' does not appear to be a valid file path.")
tt = ttLib.TTFont(font_path)
name_records = tt["name"].names
# ------------------
style = get_font_style(font_path, name_records)
"""
PlatformID == 1
NameRecord.nameID | String ID
record.nameID==0 Copyright
record.nameID==1 Family
record.nameID==2 Styles(SubFamily): Regular/Bold/Italic/Bold Italic
record.nameID==3 UniqueID
record.nameID==4 Fullname: {family} {style}
record.nameID==5 Version
record.nameID==6 Postscript Fullname: {family no space}-{style}
record.nameID==11 Preferred Family:
record.nameID==12 Preferred Styles:
"""
# Postscript name
# - no spaces allowed in family name or the PostScript suffix. should be dash delimited
postscript_name = f"{new_family_name.replace(' ', '')}-{style.replace(' ', '')}"
# modify the opentype table data in memory with updated values
for i in range(len(name_records) - 1, -1, -1):
record = name_records[i]
if record.nameID == 1:
record.string = new_family_name
elif record.nameID == 4:
record.string = f"{new_family_name} {style}"
elif record.nameID == 6:
record.string = postscript_name
else:
...
# TODO: delete other table data like WS family name
# del name_records[i]
try:
tt.save(font_path)
print(f"[OK] Updated '{font_path}' with the name '{new_family_name}'")
except Exception as e:
exit_with_error_msg(f"""
[fontname.py] ERROR: unable to write new name to OpenType name table for {font_path}.
""")
def get_font_style(font_path, name_records) -> str:
style = ""
# determine font style for this file path from name record nameID 2
for record in name_records:
if record.nameID == 2:
style = str(record)
break
# test that a style name was found in the OpenType tables of the font
if len(style) == 0:
exit_with_error_msg(f"""
[fontname.py] ERROR: unable to detect the font style from the OpenType name table in {font_path}.
Unable to complete execution of the script.
""")
return style
def exit_with_error_msg(err_msg):
sys.stderr.write(err_msg)
sys.exit(1)
def file_exists(filepath):
"""Tests for existence of a file on the string filepath"""
return os.path.exists(filepath) and os.path.isfile(filepath)
if __name__ == "__main__":
main(sys.argv[1:])