Glyph renaming

shahidr100's picture

Hi,

I have around 2000 glyphs which needs to be renamed totally as most of them are more than 32 chars and truncated to 32 chars automatically by FontForge. This has created duplicate entries i think.

What I need to do is give them a friendly name like GLYPH0001 - GLYPH2000.

Is there any script which can do this. I will select the glyphs which i want to change and run the script in order todo so.

Please help.

Thanks & Regards

NOTE: I am a newbie in fonts and fontforge.

gluk's picture

try maybe my quick script

# -*- coding: utf-8 -*-
import fontforge;

def change_name_XXXX00001(arg1,font):
   prefix=fontforge.askString("Prefix..","Prefix:",'GLYPH');
   numer=1;
   for i in font.selection.byGlyphs:
      i.glyphname=prefix+("%04d" % numer);
      numer+=1;

def EnableSel(arg1,font):
   for i in font.selection.byGlyphs:
      return True;
   return False;

fontforge.registerMenuItem(change_name_XXXX00001,EnableSel,None,
"Font",None,"Glyph_names","Change to XXXX00001");

Save code to file or download it from:
www.glukfonts.pl/temp/gluk_names.py

Thomas Phinney's picture

I take it you don't need or care about glyph-to-Unicode mapping in situations where the original encoding is lost? (Notably PDF creation workflows where the PDF is created from a PostScript file without the original font.)

If you *do* care about such things, glyph names are important and need to be done correctly.

phrostbyte64's picture

@ Thomas Phinney
I've read that before, but I'm not certain exactly what correct naming conventions might be. I use, as a example, a.salt, a.salt2 a.salt3 etc, but what do you do with the glyph which has no parent glyph - so to speak. Does it really matter as long as you assign unicodes (from the private range.)

shahidr100's picture

Thanks a lot gluk.

I am new in FontForge. How do I run the script. I am using Windows 7 64 bit.

Thanks
Shahid

shahidr100's picture

I selected 2000 glyphs. Selected "Execute Script" from File menu. Pasted the script above and pressed ok but nothing happened. I dont know whether I have done right or not??

Thanks

gluk's picture

If You want make it through "Execute Script..", You should paste this:

import fontforge;
n=fontforge.activeFont();
prefix=fontforge.askString("Prefix..","Prefix:",'GLYPH');
numer=1;
for i in n.selection.byGlyphs:
   i.glyphname=prefix+("%04d" % numer);
   numer+=1;
shahidr100's picture

Wow...thanks so much gluk. It worked like a charm....you saved me lots and lots of time.

Is there any site where I can get more info on FontForge scripts. Their site does not cover in detail.
Thanks once again.

gluk's picture

@shahidr100: you are welcome.

Info about Python scripts in Fontforge:
fontforge.org/python.html

Thomas Phinney's picture

> what do you do with the glyph which has no parent glyph - so to speak. Does it really matter as long as you assign unicodes (from the private range.)

If they are private use area encoded, then they could have uniXXXX names.

oneweioranother's picture

Hi all, I just posted this and was wondering if anyone could help with a fontforge shell script that renames the Glyph Name from the Unicode?

much thanks

Michel Boyer's picture

Here is a script that renames all glyphs to uniXXXX

for g in fnt.glyphs():
  if g.unicode != -1:
    g.glyphname = "uni%04X" % (g.unicode)

Here is one that renames all afii to uni:

import string
for g in fnt.glyphs():
  if string.find(g.glyphname,'afii') == 0:
    g.glyphname = "uni%04X" % (g.unicode)

I would personally not rename A to uni0041 but I rename all afii.

oneweioranother's picture

Michel

Thanks for your help, I ran the scripts, however they don't do the renaming required.

Let me clarify: I wanted to rename the "Glyph Name" (that's not the same as afii is it?) which currently is "uni0061" (instead of "a") and so on, back to "a" from reading the glyph's unicode number.

thanks
Wei

Michel Boyer's picture

Oh, then you use

   g.glyphname=fontforge.nameFromUnicode(g.unicode)

on the glyphs g you want to rename; cf http://fontforge.org/python.html.

Michel Boyer's picture

Of course that will not work for glyph names like uni0061.sc (or uni0061_uni1DC8 or u00611DC8) that return -1 as unicode value. You then need to parse the glyph name in order to rename it.

Michel Boyer's picture

I ran the scripts

What I wrote needs to be completed according to the way you use the code. I use such code in python scripts I call from bash shells. Above, Grzegorz wrote the script so as to call it from the GUI, using the "Execute script" window. Let me just add his lines to get a complete script to use that way:

---
fnt=fontforge.activeFont()
for g in fnt.selection.byGlyphs:
  if g.unicode != -1:
     g.glyphname= fontforge.nameFromUnicode(g.unicode)
---

You first select the glyphs to rename and then, in the "Execute script" window with that script in it you click ok. That script renames according to the unicode value, not to the hex digits that follow the uniXXXX name; it does not look at the name at all.

Now here is a script that looks at the uniXXXX name. It will rename only glyphs with a name of the form uniXXXX and it assumes glyph names that start with uni are followed by a valid hex number, nothing else; it does not check that what follows uni is a valid hex number.

---
import string
fnt=fontforge.activeFont()
for g in fnt.selection.byGlyphs:
  name=g.glyphname
  if string.find(name,'uni') == 0:
    g.glyphname=fontforge.nameFromUnicode(int(name[3:],16))
---

Again, you select the glyphs to rename, and click ok in the "Execute script" window.

When you have many scripts, it is not handy to copy them all the time in the "Execute script" window. What you can do is save them in some file, say unicode2name.py and uniname2name.py. You then click "File > Preferences > Script menu" and give a name for the menu name, say "Unicode to name"; then you click on the three dots, go to the folder containing the script, put "*.py" in the the line just above "Filter" and click "Filter"; you will see the files .py appear. You select the one you want to associate to the given menu name.

After, you can execute the script on the selected glyphs by clicking on "File > Script Menu" and the appropriate name associated to the script. You can also execute with some key combination (it is control alt digit on my mac).

A script that checks that the hex values are valid and that handles alternates (.sc, .alt, .ss02 etc) and also glyph names separated by an underscore requires splitting the glyph name and handling piecewise. Here is one that checks that the hex is valid and that can handle names of the form uniXXXXX.sc.ss02 i.e. alternames of uniXX...X

---
import string
ff=fontforge
fnt=ff.activeFont()

def ishex(h):
  return all(c in string.hexdigits for c in h)

def gname(altname):
  l = string.split(altname,'.')
  name=l[0]
  if string.find(name,'uni') == 0:
    hexd=name[3:]
    if ishex(hexd):
      l[0]= ff.nameFromUnicode(int(hexd,16))
      return '.'.join(l)
  return altname
 
for g in fnt.selection.byGlyphs:
  g.glyphname=gname(g.glyphname)
---
gluk's picture

btw, Michael

[...] When you have many scripts, it is not handy to copy them all the time in the "Execute script" window [...]

You can define own scripts in 'Tools' menu. For example first script:

import fontforge;

def rename_unival(arg1,font):
  for g in font.selection.byGlyphs:
    if g.unicode != -1:
      g.glyphname= fontforge.nameFromUnicode(g.unicode);

def EnableSel(arg1,font):
   for g in font.selection.byGlyphs:
      return True;
   return False;

fontforge.registerMenuItem(rename_unival,EnableSel,None,
"Font",None,"Glyph_names","Rename to unicode value"); 

Save them in change2uni.py in .Fontforge/python/ directory, and now You have new menu item 'Rename to unicode value' in a submenu 'Glyph_names' of the 'Tools' menu (of the Font window).

Michel Boyer's picture

That's certainly better looking than in the File menu but the documentation says there is then no shortcut. Those in "File > Script Menu" have a shortcut. Unless you have lots of them, I don't see the advantage but, since I use scripts almost exclusively from the command line, maybe I am missing something expert GUI users appreciate.

gluk's picture

Yo can define shortcut (for example key / ) in last line:

fontforge.registerMenuItem(rename_unival,EnableSel,None,
"Font","/","Glyph_names","Rename to unicode value"); 

I personally think, there are many advantages in 'Tools' menu.

Michel Boyer's picture

Yo can define shortcut

Oh, I had missed that; it is just the example in the doc that had none.

oneweioranother's picture

I would like to execute these scripts in the terminal as shell scripts... however something is wrong on my end (I'm using mf2pt1 to convert Metafonts into TrueType/Otf and FontForge is part of the process). When I try to run this script inside the FontForge gui as Execute Script:

fnt=fontforge.activeFont()
for g in fnt.selection.byGlyphs:
  if g.unicode != -1:
     g.glyphname= fontforge.nameFromUnicode(g.unicode)

I get the following error:
No built-in function or script-file Called from...

If it helps this is the part of the perl script that executes FontForge:

# Use FontForge to autohint the result.
my $user_script = 0;   # 1=script file was provided by the user; 0=created here
if (defined $ffscript) {
    # The user provided his own script.
    $user_script = 1;
}
else {
    # Create a FontForge script file.
    $ffscript = $filebase . ".pe";
    open (FFSCRIPT, ">$ffscript") || die "${progname}: $! ($ffscript)\n";
    print FFSCRIPT <<'AUTOHINT';
Open($1);
SelectAll();
RemoveOverlap();
#AddExtrema();
#Simplify(0, 2);
CorrectDirection();
#Simplify(0, 2);
RoundToInt();
AutoHint();   
Generate($1);
Generate($1:r + ".otf");
Generate($1:r + ".ttf");
Quit(0);
AUTOHINT
    ;
    close FFSCRIPT;
}

much appreciated.

Michel Boyer's picture

Run this in a terminal window

fontforge -lang=ff -c 'Print($haspython)'

and if you get 0 then your FontForge was not compiled to use Python scripts. You should get 1 for python scripts to work.

Also put your code between the tags <pre> and </pre> else it is unindented and unreadable.

Michel Boyer's picture

Here is a native fontforge script that does the renaming

Open($1)
SelectWorthOutputting()
foreach
  SetCharName(NameFromUnicode(GlyphInfo("Unicode")))
endloop
Save($2)

If you call it renam.pe then the call

fontforge -lang=ff -script renam.pe infile.sfd outfile.sfd

should do about the same as the python script you appear to be having trouble with. In fact, I just tried that script and it even renamed uni004F_uni0045.sc to O_E.sc. I don't know much native fontforge scripting and I am somewhat surprised that it did that.

oneweioranother's picture

My shell version of FontForge does run Python (not sure about my Beta Packaged version though).

The new script you wrote worked a treat though,
Thanks Michel.

Michel Boyer's picture

The FontForge on Mac Ports can be installed for python2.6 or python2.7. Of course, it is not as recent as the github version but it does what I need.

Syndicate content Syndicate content