tooling: fixes for variable font metadata
This commit is contained in:
parent
9ebede5a55
commit
dd2f374bfd
3 changed files with 85 additions and 31 deletions
4
Makefile
4
Makefile
|
|
@ -214,9 +214,9 @@ $(FONTDIR)/var/Inter-Italic.var.ttf: $(FONTDIR)/var/inter-roman-and-italic.stamp
|
||||||
touch $@
|
touch $@
|
||||||
|
|
||||||
$(FONTDIR)/var/InterV.var.ttf: $(FONTDIR)/var/Inter.var.ttf | venv
|
$(FONTDIR)/var/InterV.var.ttf: $(FONTDIR)/var/Inter.var.ttf | venv
|
||||||
. $(VENV) ; python misc/tools/rename.py --family "Inter Variable" -o $@ $<
|
. $(VENV) ; python misc/tools/rename.py --scrub-display --family "Inter Variable" -o $@ $<
|
||||||
$(FONTDIR)/var/InterV-Italic.var.ttf: $(FONTDIR)/var/Inter-Italic.var.ttf | venv
|
$(FONTDIR)/var/InterV-Italic.var.ttf: $(FONTDIR)/var/Inter-Italic.var.ttf | venv
|
||||||
. $(VENV) ; python misc/tools/rename.py --family "Inter Variable" -o $@ $<
|
. $(VENV) ; python misc/tools/rename.py --scrub-display --family "Inter Variable" -o $@ $<
|
||||||
|
|
||||||
var: \
|
var: \
|
||||||
$(FONTDIR)/var/Inter.var.ttf \
|
$(FONTDIR)/var/Inter.var.ttf \
|
||||||
|
|
|
||||||
|
|
@ -9,27 +9,43 @@ def remove_whitespace(s):
|
||||||
return WHITESPACE_RE.sub("", s)
|
return WHITESPACE_RE.sub("", s)
|
||||||
|
|
||||||
|
|
||||||
def fixup_instances_text(designspace):
|
def fixup_names(instance_or_source):
|
||||||
# makes the "text" (non-display) instances the default ones
|
instance_or_source.name = instance_or_source.name.replace(' Display', '')
|
||||||
|
if instance_or_source.styleName == 'Display':
|
||||||
|
instance_or_source.styleName = 'Regular'
|
||||||
|
else:
|
||||||
|
instance_or_source.styleName = instance_or_source.styleName.replace('Display ', '')
|
||||||
|
|
||||||
|
|
||||||
|
def fixup_source(designspace, source):
|
||||||
|
fixup_names(source)
|
||||||
|
|
||||||
|
|
||||||
|
def fixup_instance(designspace, instance):
|
||||||
|
fixup_names(instance)
|
||||||
|
|
||||||
|
psFamilyName = 'Inter'
|
||||||
|
instance.postScriptFontName = psFamilyName + remove_whitespace(instance.styleName)
|
||||||
|
instance.styleMapFamilyName = instance.styleMapFamilyName.replace(' Display', '')
|
||||||
|
|
||||||
|
# remove WWSFamilyName and WWSSubfamilyName properties
|
||||||
|
del instance.lib['com.schriftgestaltung.properties']
|
||||||
|
|
||||||
|
customParameters = instance.lib['com.schriftgestaltung.customParameters']
|
||||||
|
i = len(customParameters)
|
||||||
|
while i > 0:
|
||||||
|
i -= 1
|
||||||
|
if customParameters[i][0] == 'Has WWS Names':
|
||||||
|
del customParameters[i]
|
||||||
|
|
||||||
|
|
||||||
|
def fixup_instances(designspace):
|
||||||
i = len(designspace.instances)
|
i = len(designspace.instances)
|
||||||
while i > 0:
|
while i > 0:
|
||||||
i -= 1
|
i -= 1
|
||||||
instance = designspace.instances[i]
|
instance = designspace.instances[i]
|
||||||
if instance.name.find('Inter Display') != -1:
|
if instance.name.find('Inter Display') != -1:
|
||||||
del designspace.instances[i]
|
fixup_instance(designspace, instance)
|
||||||
|
|
||||||
|
|
||||||
def fixup_instances_display(designspace):
|
|
||||||
# makes the display instances the default ones
|
|
||||||
i = len(designspace.instances)
|
|
||||||
while i > 0:
|
|
||||||
i -= 1
|
|
||||||
instance = designspace.instances[i]
|
|
||||||
if instance.name.find('Inter Display') != -1:
|
|
||||||
if instance.styleName == 'Display':
|
|
||||||
instance.styleName = 'Regular'
|
|
||||||
else:
|
|
||||||
instance.styleName = instance.styleName.replace('Display ', '')
|
|
||||||
else:
|
else:
|
||||||
del designspace.instances[i]
|
del designspace.instances[i]
|
||||||
# change default opsz value
|
# change default opsz value
|
||||||
|
|
@ -39,11 +55,15 @@ def fixup_instances_display(designspace):
|
||||||
break
|
break
|
||||||
|
|
||||||
|
|
||||||
def fixup_postscript_instance_names(designspace):
|
def fixup_sources(designspace):
|
||||||
# make sure there are PostScript names assigned (fontmake does not create these)
|
i = len(designspace.sources)
|
||||||
psFamilyName = remove_whitespace(designspace.instances[0].familyName)
|
while i > 0:
|
||||||
for instance in designspace.instances:
|
i -= 1
|
||||||
instance.postScriptFontName = psFamilyName + remove_whitespace(instance.styleName)
|
source = designspace.sources[i]
|
||||||
|
if source.name.find('Inter Display') != -1:
|
||||||
|
fixup_source(designspace, source)
|
||||||
|
else:
|
||||||
|
del designspace.sources[i]
|
||||||
|
|
||||||
|
|
||||||
def main(argv):
|
def main(argv):
|
||||||
|
|
@ -56,10 +76,8 @@ def main(argv):
|
||||||
|
|
||||||
designspace = DesignSpaceDocument.fromfile(args.input_designspace)
|
designspace = DesignSpaceDocument.fromfile(args.input_designspace)
|
||||||
|
|
||||||
# fixup_instances_text(designspace)
|
fixup_instances(designspace)
|
||||||
fixup_instances_display(designspace)
|
fixup_sources(designspace)
|
||||||
|
|
||||||
fixup_postscript_instance_names(designspace)
|
|
||||||
|
|
||||||
designspace.write(args.output_designspace)
|
designspace.write(args.output_designspace)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -14,6 +14,7 @@ POSTSCRIPT_NAME = 6
|
||||||
PREFERRED_FAMILY = 16
|
PREFERRED_FAMILY = 16
|
||||||
TYPO_SUBFAMILY_NAME = 17
|
TYPO_SUBFAMILY_NAME = 17
|
||||||
WWS_FAMILY = 21
|
WWS_FAMILY = 21
|
||||||
|
VAR_PS_NAME_PREFIX = 25
|
||||||
|
|
||||||
|
|
||||||
FAMILY_RELATED_IDS = set([
|
FAMILY_RELATED_IDS = set([
|
||||||
|
|
@ -23,6 +24,7 @@ FAMILY_RELATED_IDS = set([
|
||||||
POSTSCRIPT_NAME,
|
POSTSCRIPT_NAME,
|
||||||
PREFERRED_FAMILY,
|
PREFERRED_FAMILY,
|
||||||
WWS_FAMILY,
|
WWS_FAMILY,
|
||||||
|
VAR_PS_NAME_PREFIX,
|
||||||
])
|
])
|
||||||
|
|
||||||
whitespace_re = re.compile(r'\s+')
|
whitespace_re = re.compile(r'\s+')
|
||||||
|
|
@ -131,7 +133,9 @@ def renameStylesGoogleFonts(font):
|
||||||
|
|
||||||
|
|
||||||
def setStyleName(font, newStyleName):
|
def setStyleName(font, newStyleName):
|
||||||
newFullName = getFamilyName(font).strip() + " " + newStyleName
|
newFullName = getFamilyName(font).strip()
|
||||||
|
if newStyleName != 'Regular':
|
||||||
|
newFullName += " " + newStyleName
|
||||||
newFullNamePs = remove_whitespace(newFullName)
|
newFullNamePs = remove_whitespace(newFullName)
|
||||||
set_full_name(font, newFullName, newFullNamePs)
|
set_full_name(font, newFullName, newFullNamePs)
|
||||||
|
|
||||||
|
|
@ -162,9 +166,24 @@ def setFamilyName(font, nextFamilyName):
|
||||||
return s, nextFamilyName
|
return s, nextFamilyName
|
||||||
|
|
||||||
# postcript name can't contain spaces
|
# postcript name can't contain spaces
|
||||||
psPrevFamilyNames = [s.replace(" ", "") for s in prevFamilyNames]
|
psPrevFamilyNames = []
|
||||||
|
for s in prevFamilyNames:
|
||||||
|
s = s.strip()
|
||||||
|
if s.find(' ') == -1:
|
||||||
|
psPrevFamilyNames.append(s)
|
||||||
|
else:
|
||||||
|
# Foo Bar Baz -> FooBarBaz
|
||||||
|
psPrevFamilyNames.append(s.replace(" ", ""))
|
||||||
|
# # Foo Bar Baz -> FooBar-Baz
|
||||||
|
p = s.rfind(' ')
|
||||||
|
s = s[:p] + '-' + s[p+1:]
|
||||||
|
psPrevFamilyNames.append(s)
|
||||||
|
|
||||||
psNextFamilyName = nextFamilyName.replace(" ", "")
|
psNextFamilyName = nextFamilyName.replace(" ", "")
|
||||||
for rec in font["name"].names:
|
found_VAR_PS_NAME_PREFIX = False
|
||||||
|
nameTable = font["name"]
|
||||||
|
|
||||||
|
for rec in nameTable.names:
|
||||||
name_id = rec.nameID
|
name_id = rec.nameID
|
||||||
if name_id not in FAMILY_RELATED_IDS:
|
if name_id not in FAMILY_RELATED_IDS:
|
||||||
# leave uninteresting records unmodified
|
# leave uninteresting records unmodified
|
||||||
|
|
@ -186,9 +205,24 @@ def setFamilyName(font, nextFamilyName):
|
||||||
old, new = renameRecord(rec, [prev_psname], psNextFamilyName)
|
old, new = renameRecord(rec, [prev_psname], psNextFamilyName)
|
||||||
else:
|
else:
|
||||||
old, new = renameRecord(rec, prevFamilyNames, nextFamilyName)
|
old, new = renameRecord(rec, prevFamilyNames, nextFamilyName)
|
||||||
|
elif name_id == VAR_PS_NAME_PREFIX:
|
||||||
|
# Variations PostScript Name Prefix.
|
||||||
|
# If present in a variable font, it may be used as the family prefix in the
|
||||||
|
# PostScript Name Generation for Variation Fonts algorithm.
|
||||||
|
# The character set is restricted to ASCII-range uppercase Latin letters,
|
||||||
|
# lowercase Latin letters, and digits.
|
||||||
|
found_VAR_PS_NAME_PREFIX = True
|
||||||
|
old, new = renameRecord(rec, prevFamilyNames, nextFamilyName)
|
||||||
else:
|
else:
|
||||||
old, new = renameRecord(rec, prevFamilyNames, nextFamilyName)
|
old, new = renameRecord(rec, prevFamilyNames, nextFamilyName)
|
||||||
# print(" %r: '%s' -> '%s'" % (rec, old, new))
|
print(" %r: '%s' -> '%s'" % (rec, old, new))
|
||||||
|
|
||||||
|
# HACK! FIXME!
|
||||||
|
# add name ID 25 "Variations PostScript Name Prefix" if not found
|
||||||
|
if not found_VAR_PS_NAME_PREFIX and nextFamilyName.find('Variable') != -1:
|
||||||
|
varPSNamePrefix = remove_whitespace(nextFamilyName)
|
||||||
|
nameTable.setName(varPSNamePrefix, VAR_PS_NAME_PREFIX, 1, 0, 0) # mac
|
||||||
|
nameTable.setName(varPSNamePrefix, VAR_PS_NAME_PREFIX, 3, 1, 0x409) # windows
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
|
|
@ -220,6 +254,8 @@ def main():
|
||||||
args.family = remove_substring(getFamilyName(font), "Display")
|
args.family = remove_substring(getFamilyName(font), "Display")
|
||||||
if not args.style:
|
if not args.style:
|
||||||
args.style = remove_substring(getStyleName(font), "Display")
|
args.style = remove_substring(getStyleName(font), "Display")
|
||||||
|
if args.style == '':
|
||||||
|
args.style = 'Regular'
|
||||||
|
|
||||||
editCount = 0
|
editCount = 0
|
||||||
try:
|
try:
|
||||||
|
|
|
||||||
Reference in a new issue