--- 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: - - -