Is there a quick/comfortable way to do this?
At the moment I use “Generate Instances” which is a real pain in the ass if you need to export more than one Instance as UFO. As far as I know there are mainly two options to add/improve this feature:
###1 – Generate Instances as one file with multiple Masters
This is probably the easiest way to implement it right away… Instead of generating all Instances as separate files, please lets generate just one file and then add all the following generated Instances as a new Master to it. This would then allow to export all of those Instances in just one additional step (via export UFO)
PS: can you please disable the function that the generated File/Master gets selects the weight/width name based on the Interpolation value! This messes up the naming in all projects which do use different interpolation value scales, which is not uncommon, e.g. using the stem-width as values for weight which makes almost every generated Master named “Light …”
###2 – Make UFO Export handle Instances as well
There are multiple ways to implement this nicely, here just two of them
Add Checkbox to export Instances (active) as UFO
Or similar to the Master list (in the export window) have a Instance list next to it.
Ok, thanks. Will try to figure it out with a script … just hoped that this would get implemented at some point.
I can partly understand that it is not in the export UI … but nevertheless, it would be great if the “Generating Instances” could be improved! It would be super easy for you to implement and I can’t see any downsides, or am I missing something?
Trying to export .ufo files from the instances - this doesn’t work for me unfortunately (see traceback):
(sorry indents are missing
import GlyphsApp
Font = Glyphs.font
for index, i in enumerate(Font.instances):
username = "luke"
f = i.interpolatedFont()
f.save("/Users/%s/Desktop/%s%s.ufo:" % (username, i.familyName, i.name))
traceback:
File "<string>", line 5, in <module>
TypeError: 'NSKVONotifying_GSFont' object is not callable
(edit: added three grave before and after the code block)
import GlyphsApp
UFODir = GetFolder()
for i in Glyphs.font.instances:
iF = i.interpolatedFont
iF.save("{0}/{1} {2}.ufo".format(UFODir, iF.familyName, i.name))
And here is what I ended up with (not so nice, but works as well ^^) Export Instances as UFO.py.zip (1.4 KB)
(with this you can also manipulate the filename on export)
Maybe someone is willing to help with this? (simply to hot to code today)
Basically the other way around - something like this:
I would like to create a file with 2 masters from 2 .ufo files by using GetFolder().
Afterwards it would be great to set the weight value for the masters e.g.
master1 = 0
master2 = 1000
and create some instances in between with some variable weight values:
master1_instance = 0
intermediate_instance = 300
intermediate_instance2 = 500
master2_instance = 1000
I came up with these lines of weird code, but got stuck in the middle, because my brain is melting…
import GlyphsApp
from vanilla.dialogs import getFile
getFolderwithFiles = getFolder()
if getFolderwithFiles:
folderPath = getFolderwithFiles[0]
newFont = GSFont()
newFont.familyName = "My New Font"
newMasters = []
for dirname, subdirs, files in os.walk(folderPath):
if dirname == folderPath:
pass
if dirname.split("/")[-1] == "glyphs":
pass
else:
sourceFont = Glyphs.open(dirname, False)
newMasters.append(sourceFont)
print newMasters
Hey Georg,
I think there is a bug somewhere here …
It seems to me as if the script is executing too fast. ^^
When I’m trying to append the interpolatedFont as a Master it always ends up empty. Is there any way to check if the interpolatedFont is actually there and then append it as a Master … ?
font = Glyphs.fonts[0]
interpolated_font = font.instances[0].interpolatedFont
print interpolated_font
print interpolated_font.masters[0]
until here everything works as expected and then…
font.masters.append(interpolated_font.masters[0])
… an empty Master gets appended.
Even the following is not working, though the generated new font clearly has everything in place.
@Luke
Sorry, that I did not respond to your last post!
But I just don’t know where you got stuck, could you elaborate on a specific problem otherwise it’s really hard to help …
What do you mean by empty master. That then master info is empty? You should make a copy of then master before adding it to a new font as it shouldn’t be in two fonts at once.
@Manuel thank you very much for your reply! I found a code snipped that helped me to get a step further (it’s less hot today - still need to figure out the best way to sort the masters (maybe weightClass) and add some instances in between - this is were I am at the moment (doesn’t look nice, but works for me):
import GlyphsApp
from vanilla.dialogs import getFolder
master1weight = 0
master2weight = 1000
getFolderwithFiles = getFolder()
if getFolderwithFiles:
folderPath = getFolderwithFiles[0]
newMasters = []
for dirname, subdirs, files in os.walk(folderPath):
if dirname == folderPath:
pass
if dirname.split("/")[-1][-4:] != ".ufo":
pass
else:
newMasters.append(dirname)
#print newMasters
if len(newMasters) == 2:
f1 = GSFont(newMasters[0])
f2 = GSFont(newMasters[1])
f1.addFontAsNewMaster_(f2.masters[0])
f1.instances.append(f2.instances[0].copy())
Glyphs.fonts.append(f1)
## setting weight values for 2 masters
Glyphs.font.masters[0].weightValue = master1weight
Glyphs.font.masters[1].weightValue = master2weight
and there is another odd thing… the instances in the new font are still looking exactly the same as in the original, even though the masters are empty!
I tried to just add .copy() to the new masters and instances:
# Add new Masters
for active_instance_font in instances_as_fonts:
new_font.masters.append(active_instance_font.masters[0].copy())
# Add all original instances
new_font.instances = () # empty Instances first
for instance in all_original_instances:
new_font.instances.append(instance.copy())
Now the instances are empty as well (which is at least a more expected behaviour with empty masters) … so yes even with this the masters are still empty
Adding the master will only add the GSFontMaster object to the master list. You need to add the layers for each glyph, too.
The font object has a method that takes care of it: font.addFontAsNewMaster_(master)
''' makes a multiple master file from 2 ufo (in folder) and adds 3 instances + sets names and weightValues'''
import GlyphsApp
from vanilla.dialogs import getFolder
from operator import itemgetter
from collections import OrderedDict
master1weight = 0
master2weight = 1000
instances = {"Medium":300,"Semibold":500,"Bold":700}
instances = OrderedDict(sorted(instances.items(), key=itemgetter(1)))
for k,v in instances.items():
print k,v
getFolderwithFiles = getFolder()
if getFolderwithFiles:
folderPath = getFolderwithFiles[0]
newMasters = []
for dirname, subdirs, files in os.walk(folderPath):
if dirname == folderPath:
pass
if dirname.split("/")[-1][-4:] != ".ufo":
pass
else:
newMasters.append(dirname)
# sort the masters (by stylename in .ufo filename)
sortation = ['Thin', 'Extralight', 'Light', 'Semilight', 'Regular', 'Medium', 'Semibold', 'Demibold', 'Bold', 'Black']
indices = {c: i for i, c in enumerate(sortation)}
finalMasterdict = {}
for k, v in indices.items():
for a in newMasters:
if k in a.split("/")[-1]:
finalMasterdict[v] = a
if len(finalMasterdict.keys()) == 2:
master1 = sorted(finalMasterdict.items())[0][1]
master2 = sorted(finalMasterdict.items())[1][1]
f1 = GSFont(master1)
f2 = GSFont(master2)
f1.addFontAsNewMaster_(f2.masters[0])
## adding instances
for i in range(len(instances.keys())+1):
f1.instances.append(f2.instances[0].copy())
Glyphs.fonts.append(f1)
## changing instances
for i, instance in enumerate(f1.instances):
if i == 0:
instance.weightValue = master1weight
if i == len(instances.keys())+1:
instance.weightValue = master2weight
else:
try:
instance.weightValue = instances.items()[i-1][1]
instance.name = str(instances.items()[i-1][0])
instance.weight = str(instances.items()[i-1][0])
except IndexError:
pass
## setting weight values for 2 masters
Glyphs.font.masters[0].weightValue = master1weight
Glyphs.font.masters[1].weightValue = master2weight
A small (final) update, fixed some things. cheers.
import GlyphsApp
from vanilla.dialogs import getFolder
from operator import itemgetter
from collections import OrderedDict
master1weight = 0
master2weight = 1000
instances = {"Medium":300,"Semibold":500,"Bold":700}
#instances = {"Semilight":450}
instances = OrderedDict(sorted(instances.items(), key=itemgetter(1)))
getFolderwithFiles = getFolder()
if getFolderwithFiles:
folderPath = getFolderwithFiles[0]
print folderPath
newMasters = []
for dirname, subdirs, files in os.walk(folderPath):
if dirname == folderPath:
pass
if dirname.split("/")[-1][-4:] != ".ufo":
pass
else:
newMasters.append(dirname)
# sort the masters (by stylename in .ufo filename)
sortation = ['Thin', 'Extralight', 'Light', 'Semilight', 'Regular', 'Medium', 'Semibold', 'Demibold', 'Bold', 'Black']
indices = {c: i for i, c in enumerate(sortation)}
finalMasterdict = {}
for k, v in indices.items():
for a in newMasters:
if k in a.split("/")[-1]:
finalMasterdict[v] = a
if len(finalMasterdict.keys()) == 2:
master1 = sorted(finalMasterdict.items())[0][1]
master2 = sorted(finalMasterdict.items())[1][1]
f1 = GSFont(master1)
f2 = GSFont(master2)
f1.addFontAsNewMaster_(f2.masters[0])
## adding instances
for i in range(len(instances.keys())+1):
f1.instances.append(f2.instances[0].copy())
Glyphs.fonts.append(f1)
## setting weight values for 2 masters
Glyphs.font.masters[0].weightValue = master1weight
Glyphs.font.masters[1].weightValue = master2weight
## changing instances weight names and values
for i, instance in enumerate(f1.instances):
if i == 0:
instance.weightValue = master1weight
instance.name = f1.masters[0].name
if i == len(f1.instances)-1:
instance.weightValue = master2weight
instance.name = f2.masters[0].name
if i != 0 and i != len(f1.instances)-1:
instance.weightValue = instances.items()[i-1][1]
instance.name = str(instances.items()[i-1][0])
instance.weight = str(instances.items()[i-1][0])
#CustomParameters
familyName = f1.familyName
styleName = str(instances.items()[i-1][0])
instance.setCustomParameter_forKey_(familyName+"-"+styleName , "postscriptFontName")
instance.setCustomParameter_forKey_(familyName+" "+styleName , "postscriptFullName")
instance.setCustomParameter_forKey_(familyName+" "+styleName , "styleMapFamilyName")