SOLVED Can “default” checkboxes in font info actually store that value in the UFO?
-
Currently the "default value" checkboxes in font info only flag to internal RF processes to auto-generate a default value in that field upon generate.
Problem: if running processes external to RF (FDK generation in Terminal for instance), those values aren't written into the UFO and can therefore raise a flag.
Could the "default value" checkbox just store the actual value in the UFO when checked?
Currently writing a script to write it to the UFO on save, but seems messy.
TIA,
Ryan
-
@gferreira Makes sense, thanks very much!
-
hello @ryan,
Is there a disadvantage to—when changing family name and style name in Font Info, with default checkboxes checked—ps names being stored in the ufo?
I think so: it goes against the DRY principle and would actually increase the chance of mismatched data down the line (for example if
familyName
orstyleName
are changed with a script or without the checkbox).if you generate the fonts with
font.generate
or withufo2fdk.OTFCompiler
, all default values are calculated automatically for you. this is very convenient. special cases can be handled with a script, as you’re doing.below is a modified version of your script, which stores the default values in the font when it is saved. it uses
getAttrWithFallback
to calculate the defaults. (I’ve added a window to toggle it ON/OFF while testing)from ufo2fdk.fontInfoData import getAttrWithFallback from vanilla import FloatingWindow, CheckBox from mojo.events import addObserver, removeObserver from defconAppKit.windows.baseWindow import BaseWindowController class psNameGenerator(BaseWindowController): def __init__(self): self.w = FloatingWindow((123, 44)) self.w.button = CheckBox((10, 10, -10, 24), 'activate', value=False, callback=self.toggleObserverCallback) self.setUpBaseWindowBehavior() self.w.open() def psNameChange(self, notification): f = notification["font"] psNames = ['postscriptFontName', 'postscriptFullName', 'postscriptWeightName'] print(f'saving {f.info.familyName} {f.info.styleName}...\n') for psName in psNames: value = getAttrWithFallback(f.info, psName) setattr(f.info, psName, value) print(f'\t{psName}: {getattr(f.info, psName)}') f.save() print('\n...done.\n') def toggleObserverCallback(self, sender): if sender.get(): print('observer is ON\n') addObserver(self, "psNameChange", "fontDidSave") else: print('observer is OFF\n') removeObserver(self, 'fontDidSave') def windowCloseCallback(self, sender): removeObserver(self, 'fontDidSave') super(psNameGenerator, self).windowCloseCallback(sender) psNameGenerator()
hope this makes sense… cheers!
-
@frankrolf I'm often working with variable fonts in a quick-and-dirty fashion, versioning, potentially delivering variable logotypes to clients to test. Can get messy very fast, and a mismatched set of ps names can be a confusing speed bump. The only thing I'm trying to avoid is postscript names being empty when needed externally of RF. Is there a disadvantage to—when changing family name and style name in Font Info, with default checkboxes checked—ps names being stored in the ufo?
I've experienced this for a while, and am only now surfacing it because the confusion recently came up amongst friends.
In the meantime, prior to any replies here, I wrote a pretty clunky script (should potentially rewrite once I understand above reply) to keep this updated. Would love to not need something like this.
from mojo.events import addObserver class postScriptFontNameGen: def __init__(self): addObserver(self, "psNameChange", "fontDidSave") def psNameChange(self, notification): f = notification["font"] # set postscript names if f.info.familyName != None and f.info.styleName != None: attributes = { 'postscriptFontName': str(f.info.familyName + "-" + f.info.styleName).replace(" ", ""), 'postscriptFullName': str(f.info.familyName + f.info.styleName).replace(" ", "") } for attr, value in attributes.items(): setattr(f.info, attr, value) # set postscript weight name if f.info.openTypeOS2WeightClass != None: ranges = { 100: "Thin", 200: "Extra-light", 300: "Light", 400: "Normal", 500: "Medium", 600: "Semi-bold", 700: "Bold", 800: "Extra-bold", 900: "Black", } os2_w = f.info.openTypeOS2WeightClass f.info.postscriptWeightName = "Thin" for attr, value in ranges.items(): if os2_w >= attr: f.info.postscriptWeightName = value else: f.info.postscriptWeightName = "Normal" f.save() postScriptFontNameGen()
-
What keeps you from just saving the value (such as the PS font name) into the UFO? Check the box once and you’re done.
Does the font name change that often? ;-)FWIW, I’d rather confirm some of Robofont’s suggestions by unchecking the ✅
Use Default Value
box, than hunting for “helpfully” set default values in my UFO file.So – please reconsider your suggestion! :-)
-
the default values are calculated by ufo2fdk getAttrWithFallback
from ufo2fdk.fontInfoData import getAttrWithFallback from defcon import Info info = Info() info.descender = -250 print(getAttrWithFallback(info, "openTypeOS2WinDescent")) info.openTypeOS2WinDescent = 350 print(getAttrWithFallback(info, "openTypeOS2WinDescent"))
also see the defconAppKit fontInfoView