Changing glyph names and updating feature code

Is there any discussion on this or can you advise how best to do this . . .
I want to change glyph suffixes (i.e. .small to .sc). Will Glyphs update all the occurances in Classes and Feature code? Is there an option to do this when I search and replace?

If the code is auto generated (and for the small caps that would be a good idea) you need to update the code. Other than that, you need to search/replace yourself.

There’s no ability to do this but for a range of glyphs?

That looks like someone else’s script or plugin.

For simply renaming glyphs, there’s Edit > Find > Find and Replace (Shift-Command-F).

For something like changing the glyphs from .small suffixes to .sc, I’d select all the glyphs I wanted to change (or all the glyphs), use Find and Replace (Shift-Command-F), entering .small in the Find field and .sc in the Replace field.

That doesn’t help with the OpenType features, of course. But, if you’re moving to Glyphs autogenerated features based on naming, then it may not matter for some features.

The screen grab is FontLab7. At the moment it’s easy and quick to open the .glyphs file in FL7 run the changes and save as .glyphs. I tend to have a mix of auto and manual feature code and classes.

Have you tried tokens? Tutorial is on its way, there is a brief description in the blog post.

Immediate need is solved but I’ll take a look at the tutorial as and when.

I still have this need.
I want to change ā€˜i.dot’ to ā€˜idotaccent’ and have all the feature code update accordingly.
Just changing the glyph name doesn’t update the feature code. Is there a way to do this in Glyphs as there is in FontLab?

Agreed. It’d be handy, when renaming a glyph, if Glyphs would check if the old name appeared in any feature code, and if so, if it would ask if the name should be changed there too.

It’s on the list for a future version. Meanwhile, I’ll see what I can do with a script.

1 Like

Any update on this since 2022?

I have an old font where I would like to change a whole bunch of custom glyph names to Glyphs standards in order for various automatic features (like mark positioning) to work. Use Custom Names was enabled previously, but is now turned off.

As far as I can tell, I’ve currently got these options:

  • select all the glyphs I want to change and do Update Glyph Info to fix the glyph names – but the feature code, which is all manual, will then break
  • open the Glyphs file in a text editor and manually find and replace each glyph name I want to change throughout the file – works, but there’s at least 200 glyphs to change, so that’s a lot of find-and-replace

For the latter option, some of it can be grouped so it’s not quite a separate search for every glyph (e.g., …comb is, I think, always …nosp), but some glyph names are just completely different, so there will still be a lot of glyph-level searching; for example, what Glyphs expects to be called hungarumlautcomb is currently named acutedblnosp, brevebelowcomb is brevesubnosp and downtackbelowcomb is tackdownsubnosp.

It would be so extremely useful if there were some way to have the app automatically update all references to each glyph name when you Update Glyph Info, even in manual feature code.

I agree this would be useful. For the time being, this should be easily solvable with a script. Have a look at GSFont.features and GSFeature.code.

From there, it’s a simple .replace(str1, str2). You can run Update Glyph Info from a script with GSGlyph.updateGlyphInfo().

1 Like

I shall have a look at that and see if I can make it work. So far, my forays into Glyph scripting (and Python in general, which I’ve never really had cause to use) have been very basic and limited.

Don’t hesitate to ask if you run into issues. Here’s the basic structure of your script:

  1. Loop over all glyphs with for glyph in Font.glyphs.
  2. For each glyph, store a variable with the old name (such as old_name = glyph.name).
  3. Run glyph.updateGlyphInfo() for that glyph.
  4. Search for the old_name in the feature code and replace it with the new glyph name:
for feature in Font.features:
    feature.code = feature.code.replace(old_name, glyph.name)

Don’t forget to back up your file beforehand.

1 Like

There is a function that can help with the replace:

feature.code = GSGlyphsInfo.convertNames_inString_(changedGlyphNames, feature.code)

it should check that only full glyph names are replaced. Otherwise you might replace partially names.

3 Likes

@Georg Is that function documented anywhere? I don’t see it in the core GSGlyphsInfo class. What exactly is the changedGlyphNames parameter? An array with a ā€˜from’ and ā€˜to’ value or something like that?

changedGlyphNames is a dict like :

changedGlyphNames = {
                      "oldName1":"newName1",
                      "oldName2":"newName2",
}
1 Like

So, coming back to this again now, because I’m now trying to nice-name a 20-year-old font (imported from the .ttf file) with nearly 4,000 glyphs, nearly all named by their unicode points. There are a few classes and a whole bunch of feature prefixes and features not automatically generated.

I managed to almost get everything to work with this code:

changed = {}

for glyph in Font.glyphs:
	old_name = glyph.name
	glyph.updateGlyphInfo()
	if glyph.name != old_name: changed[old_name] = glyph.name

for ft in Font.features:
	ft.code = GSGlyphsInfo.convertNames_inString_(changed, ft.code)

for pf in Font.featurePrefixes:
	pf.code = GSGlyphsInfo.convertNames_inString_(changed, pf.code)

for cl in Font.classes:
	cl.code = GSGlyphsInfo.convertNames_inString_(changed, cl.code)

It worked once (took about 20–30 seconds to run), except that I had forgotten to change ft.code to pf.code when replacing in the prefixes, so they got all messed up. (Immediately closed the file without saving to make sure none of the messed up stuff got saved.)

So I fixed that, but now when I reopen the Glyphs file and run the script again, Glyph starts SBOD’ing, and after a while, I get a pop-up that tells me to close apps because I’m running out of memory – and Glyphs is using 25 GB of memory! So something’s clearly not right and leaking memory something terrible… but what?

I managed to get this to work by doing it in chunks, looping through selected glyphs instead of all glyphs in the font.

Updating about 50–100 glyphs at a time worked fine (took somewhere between five and ten seconds per run), although memory usage increased accumulatively by about 100 MB each time I ran the script.

When I tried it with a larger number of glyphs selected (400 or so), Glyphs again hung, with memory usage climbing continuously, and quite rapidly, until I force-quite the app.

When importing a otf/ttf, you can set disable ā€œKeep Glyphs name in imported filesā€. That way all the covering is done on import.