---
title: "Mass renaming glyphs in fontforge with python"
date: 2023-09-02
---

I've got a book that I've roughly typeset in XeTeX, and out of curiosity I decided to port it to Groff. I wanted to see how similar I could get it to look and I started typesetting in MS Song since that looked like what XeTeX had picked (for this project my tex file didn't specify a font).

I soon noticed that XeTeX had used a very similar but slightly different font, Fandol Song. TeXlive had installed an OTF copy of Fandol Song at /usr/share/texlive/texmf-dist/fonts/opentype/public/fandol/FandolSong-Regular.otf, so I used the [install-font.sh script from the creator of the groff mom macros](https://www.schaffter.ca/mom/mom-05.html#install-font) to prepare it for use with Groff, but Groff complained that all of my CJK glyphs couldn't be found:

```
groff -mzh -Kutf8 -Tps main.tr > main.ps
troff: main.tr:12: warning: can't find special character 'u53CD'
troff: main.tr:12: warning: can't find special character 'u5012'
troff: main.tr:12: warning: can't find special character 'u8BF4'
troff: main.tr:12: warning: can't find special character 'u662F'
troff: main.tr:12: warning: can't find special character 'u5F97'
troff: main.tr:12: warning: can't find special character 'u4E86'
troff: main.tr:12: warning: can't find special character 'u6D41'
troff: main.tr:12: warning: can't find special character 'u884C'
troff: main.tr:12: warning: can't find special character 'u6027'
troff: main.tr:12: warning: can't find special character 'u611F'
troff: main.tr:12: warning: can't find special character 'u5192'
```

Eventually I traced the problem down to the format of the glyph names: my other CJK fonts seem to use a glyph name like "uni4E86" for the glyph representing unicode codepoint U+4E86 (了), whereas TeX's FandolSong file had a glyph name like "GB1.2580", with 2580 corresponding to the Character ID used for 了 in the Adobe-GB1-6 character collection.

I'm sure this isn't the proper way to fix this, but I opted to just run a fontforge script using the python API to explicitly reset the glyph name for each character in the CJK Unified Ideographs unicode block which spans U+4E00 - U+9FFF:

```
myfont = fontforge.open("/usr/share/texlive/texmf-dist/fonts/opentype/public/fandol/FandolSong-Regular.otf")
sel = myfont.selection.all()

for glyph in sel.byGlyphs:
 if 0x4e00 <= glyph.unicode <= 0x9fff:
   glyph.glyphname = f"uni{glyph.unicode:04X}"

myfont.save("/tmp/FandolSongR.ttf")
```

Useful links:

- <https://support.stmdocs.in/wiki/index.php?title=Using_TrueType_fonts_with_pdfTeX>
- <https://kleshwong.com/blog/post/composing-pdf-on-linux-happily-as-an-non-latin-coder/>
- <https://silnrsi.github.io/FDBP/en-US/Adobe_Glyph_List.html>