summaryrefslogtreecommitdiff
path: root/misc/tools/fix-static-display-names.py
blob: 33789c47f9ff78a3ce6791f6c9b4ad6fc4541b5f (plain)
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
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
import sys, os, os.path, argparse, re
from fontTools.ttLib import TTFont

WINDOWS_ENGLISH_IDS = 3, 1, 0x409
MAC_ROMAN_IDS = 1, 0, 0

LEGACY_FAMILY       = 1
SUBFAMILY_NAME      = 2
TRUETYPE_UNIQUE_ID  = 3
FULL_NAME           = 4
POSTSCRIPT_NAME     = 6
PREFERRED_FAMILY    = 16
TYPO_SUBFAMILY_NAME = 17
WWS_FAMILY          = 21
WWS_SUBFAMILY       = 22

whitespace_re = re.compile(r'\s+')


def remove_whitespace(s):
  return whitespace_re.sub('', s)


def normalize_whitespace(s):
  return whitespace_re.sub(' ', s)


def remove_substring(s, substr):
  # examples of remove_substring(s, "Display"):
  #   "Inter Display"   => "Inter"
  #   "Display Lol"     => "Lol"
  #   "Foo Display Lol" => "Foo Lol"
  #   " Foo   Bar Lol " => "Foo Bar Lol"
  return normalize_whitespace(s.strip().replace(substr, '')).strip()


def getStyleName(font):
  nameTable = font["name"]
  for plat_id, enc_id, lang_id in (WINDOWS_ENGLISH_IDS, MAC_ROMAN_IDS):
    for name_id in (TYPO_SUBFAMILY_NAME, SUBFAMILY_NAME):
      r = nameTable.getName(
        nameID=name_id, platformID=plat_id, platEncID=enc_id, langID=lang_id)
      if r is not None:
        return r.toUnicode()
  raise ValueError("style name not found")


def print_relevant_names(nameTable):
  names = {
    LEGACY_FAMILY: "LEGACY_FAMILY",
    TRUETYPE_UNIQUE_ID: "TRUETYPE_UNIQUE_ID",
    FULL_NAME: "FULL_NAME",
    POSTSCRIPT_NAME: "POSTSCRIPT_NAME",
    PREFERRED_FAMILY: "PREFERRED_FAMILY",
    WWS_FAMILY: "WWS_FAMILY",
    WWS_SUBFAMILY: "WWS_SUBFAMILY",
    SUBFAMILY_NAME: "SUBFAMILY_NAME",
    TYPO_SUBFAMILY_NAME: "TYPO_SUBFAMILY_NAME",
  }
  for rec in nameTable.names:
    name_id = rec.nameID
    name = names.get(name_id)
    if name:
      print("%-19s  #%-2d  %s" % (name, name_id, rec.toUnicode()))


def main():
  argparser = argparse.ArgumentParser(
    description='Rename family and styles of static "Inter Display" fonts'
  )
  a = lambda *args, **kwargs: argparser.add_argument(*args, **kwargs)
  a('-o', '--output', metavar='<file>',
    help='Output font file. Defaults to input file (overwrite)')
  a('input', metavar='<file>', help='Input font file')
  args = argparser.parse_args()

  infile = args.input
  outfile = args.output or infile

  font = TTFont(infile, recalcBBoxes=False, recalcTimestamp=False)

  family = "Inter Display"
  style = remove_substring(getStyleName(font), "Display")
  isItalic = style.find('Italic') != -1
  if style == '':
    style = 'Regular'

  # See https://learn.microsoft.com/en-us/typography/opentype/spec/name
  nameTable = font["name"]

  fullName = family + " " + style
  fullNamePs = remove_whitespace(family) + "-" + remove_whitespace(style)

  try:
    # print_relevant_names(nameTable)

    # set full name
    nameTable.setName(fullName, FULL_NAME, 1, 0, 0)     # mac
    nameTable.setName(fullName, FULL_NAME, 3, 1, 0x409) # windows
    nameTable.setName(fullNamePs, POSTSCRIPT_NAME, 1, 0, 0)     # mac
    nameTable.setName(fullNamePs, POSTSCRIPT_NAME, 3, 1, 0x409) # windows

    for rec in nameTable.names:
      id = rec.nameID
      if id == TRUETYPE_UNIQUE_ID: # ID 3
        # Format:
        #   version ";" "git-" git-tag ";" foundry-tag ";" ps_family "-" ps_style
        # E.g.
        #   "4.001;git-4de559246;RSMS;Inter-DisplayThinItalic"
        id = rec.toUnicode().split(";")
        id[3] = fullNamePs
        rec.string = ";".join(id)
      elif id == LEGACY_FAMILY: # ID 1
        rec.string = family + ' ' + style
      elif id == SUBFAMILY_NAME: # ID 2
        rec.string = 'Italic' if isItalic else 'Regular'
      elif id == PREFERRED_FAMILY: # ID 16
        rec.string = family
      elif id == WWS_FAMILY: # ID 21
        rec.string = family
      elif id == WWS_SUBFAMILY: # ID 22
        rec.string = style
      elif id == TYPO_SUBFAMILY_NAME: # ID 17
        rec.string = style

    # print("————————————————————————————————————————————————————")
    # print_relevant_names(nameTable)

    font.save(outfile)
  finally:
    font.close()


if __name__ == '__main__':
  main()