How to add name table entries with FontTools?

Paul van der Laan
Paul van der Laan Posts: 242
edited August 2014 in Type Design Software
I'd like to manipulate name table data in a number of generated font files. So far I discovered how to access (and manipulate) name table entries that are already defined in the file:
from fontTools import ttLib

ttPath = '/Volumes/test.ttf'

ttFont = ttLib.TTFont(ttPath)

nameTable = ttFont['name'].names

print nameTable

>> [<NameRecord NameID=0; PlatformID=1; LanguageID=0>, ... ]
But what I'd like to do is to add new entries. I suppose I need to construct new NameRecord objects first in order to append them to the name table, but I have no idea how to achieve this.

Any pointers?

Comments

  • You can generalize from the technique described here:

    1. Extract the name table: ttx -t name test.ttf

    2. Edit the resulting XML file (test.ttx) as you wish.

    3. Merge it back into your font: ttx -m test.ttf test-edited.ttx

    There may be a way to do the same work within Python via direct manipulation of data structures. But since ttx is designed to convert things to XML and back, I think it’s more prudent to manipulate the XML.
  • Thanks for the answer, Matthew!

    I know TTX is great for doing this stuff, but still I’d prefer to do this directly in Python.
  • Never mind, I found it. This will do the trick:
    from fontTools.ttLib.tables._n_a_m_e import NameRecord

    myRecord = NameRecord()
    myRecord.nameID = 128
    myRecord.platformID = 64
    myRecord.platEncID = 32
    myRecord.langID = 16
    myRecord.string = 'testing'

    ttfont['name'].names.append(myRecord)
  • I was looking for something like the above example, and this snippet is working well for me. Thanks Paul!
  • Jens Kutilek
    Jens Kutilek Posts: 364
    edited September 2019
    There also is a helper method now which was not around in 2014:
    table__n_a_m_e.addMultilingualName(self, names, ttFont=None, nameID=None, windows=True, mac=True)
    It will choose a free name ID (if you pass nameID=None) automatically and return it. 'names' is a dictionary with the name in multiple languages, such as {'en': 'Pale', 'de': 'Blaß', 'de-CH': 'Blass'}

    Or, similar, but simpler if you don't want multilingual entries:
    table__n_a_m_e.addName(self, string, platforms=((1, 0, 0), (3, 1, 0x409)), minNameID=255)