I got some TTF files which have broken character placement – the cyrillic letters were at the
Latin-1 Supplement
block of the Unicode table. However I tried (different keyboard layouts, locales, etc.) I couldn’t input those characters anywhere, hence I was not able to use the TTF fonts.
I hacked up a python script that tries to copy the characters from where they are located in the broken files to their right position in the Unicode table (starting from 0×410).
The script uses the fontTools library and is really a dirty piece of work (it even swears, sometimes) as it just skips files where an exception is thrown from the fontTools library.
Honestly, I have little idea why some of the files corrupt the TTFile object character maps (tables), but I’m glad I got most files fixed.
Also, I’m not really sure what are the different cmap “formats” that are located in every TTFile object. But I guess it’s ok as long as I got something working.
#!/usr/bin/env python
from fontTools import ttLib
import getopt
import sys
def fixFont(filename):
try:
ttf = ttLib.TTFont(filename)
except IOError:
print filename + ' does not exist. Skipping to next file.'
return
# There are a few cmap tables inside a ttf object (in different 'formats'), but they apparantely are all synced with each other
for ti in range(0,3):
try:
cmap = ttf['cmap'].tables[ti].cmap
except Exception:
print 'Fucked up stuff.. Skipping.'
return
# letter count -- small + capital letters
lc = 62
# in the broken ttfs, cyrillic chars start from a broken index
broken = 0xc0
# where cyrillic chars should start from in the fixed ttf
fixed = 0x410
#just copy all the cyrillic chars to where they belong
for b,f in zip(range(broken,broken+lc+1),range(fixed,fixed+lc+1)):
try:
cmap[f] = cmap[b]
except KeyError:
import fontTools.unicode
print 'The font does not contain the character ' + fontTools.unicode.Unicode[b] + '. Skipping to next character.'
newfname = filename[:-4]+'_fixed.'+'ttf'
try:
ttf.save(newfname)
return
except Exception:
print 'Trying another table...'
if __name__ == "__main__":
for filename in sys.argv[1:]:
if filename.lower()[-3:] != 'ttf':
print filename + ': not a TTF file. Skipping to next file.'
else:
fixFont(filename)