fonttools: Error for cmap in saving a subset font: "OverflowError: unsigned short is greater than maximum"

I have a script that makes a “trial font” by subsetting a font, then assigning cut-out unicodes to a single glyph.

This has worked well for me many times, but I am currently confused by an error that is triggered when I try to save a modified font in the script:

Traceback (most recent call last):
  File "/Users/stephennixon/project/build/helpers/make-trial-font.py", line 234, in <module>
    main()
  File "/Users/stephennixon/project/build/helpers/make-trial-font.py", line 209, in main
    tempFont.save(tempFontPath.replace(f".temporary.{filetype}",f".{nameSuffix}.{filetype}"))
  File "/Users/stephennixon/project/venv/lib/python3.10/site-packages/fontTools/ttLib/ttFont.py", line 185, in save
    writer_reordersTables = self._save(tmp)
  File "/Users/stephennixon/project/venv/lib/python3.10/site-packages/fontTools/ttLib/ttFont.py", line 225, in _save
    self._writeTable(tag, writer, done, tableCache)
  File "/Users/stephennixon/project/venv/lib/python3.10/site-packages/fontTools/ttLib/ttFont.py", line 658, in _writeTable
    tabledata = self.getTableData(tag)
  File "/Users/stephennixon/project/venv/lib/python3.10/site-packages/fontTools/ttLib/ttFont.py", line 680, in getTableData
    return self.tables[tag].compile(self)
  File "/Users/stephennixon/project/venv/lib/python3.10/site-packages/fontTools/ttLib/tables/_c_m_a_p.py", line 184, in compile
    chunk = table.compile(ttFont)
  File "/Users/stephennixon/project/venv/lib/python3.10/site-packages/fontTools/ttLib/tables/_c_m_a_p.py", line 911, in compile
    charCodeArray = array.array("H", endCode + [0] + startCode)
OverflowError: unsigned short is greater than maximum

Other issues suggest that the fix might be something like setting the format of the post table, but this seems to be a problem relating to the cmap table. (Also, setting a format 3 post table doesn’t seem to make a difference, in my initial attempts.)

The cmap table in the current font is version 4, similar to other fonts I’ve successfully run this script on.

Is there anything else I might try to get past this?

Thanks so much for any advice!

About this issue

  • Original URL
  • State: closed
  • Created 2 years ago
  • Comments: 19 (9 by maintainers)

Most upvoted comments

Alternatively you could rebuild the cmap from scratch. FontBuilder.setupCharacterMap() makes this fairly trivial, and will add the right subtables depending on the character set. Something like:

from fontTools.fontBuilder import FontBuilder

newCmap = {....}  # code points => glyph names
fb = FontBuilder(font=<a-TTFont-instance>)
fb.setupCharacterMap(newCmap)
fb.save(<new-file-name>)

glad it worked

should I be calling the subsetter as a python module, somehow, and feeding in the TTFont?

up to you; in that case at the very least you’d need to create an subset.Options() passing in as keyword arguments all the options you want, then instantiate a subset.Subsetter(options), call populate method with the set of unicodes or glyphs to keep, and finally call its subset(font) method which will modify the TTFont instance in-place. Something like this

    from fontTools import subset
    options = subset.Options(glyph_names=True, name_IDs=["*"], notdef_outline=True)
    subsetter = subset.Subsetter(options)
    subsetter.populate(unicodes=["*"])
    subsetter.subset(font)
    font.save(output_file)