changing font 'version' metadata

When i generate a font using makeotf directly or robofont, it adds in a Version string (see the attached screenshot) the versions of each library that built the font (in this case, makeotflib, hotconv, et al).

What i would like to do is specify a version string on generation (or even after the fact, whatever), but i don't actually know how to modify this field for a generated font. I suspect this is a trivial operation, but it is eluding me.

primarily, i would like to be able to tag a release with a short hg or git commit hash so i can see how old an installed version is when i switch to a new computer or ask a friend if they have the latest version. right now, i have to look at the file creation date and sorta just guess, but i'd rather command-i the file and be able to see how aged the file is.

thanks for any help.

Comments

  • Since you have AFDKO installed, which includes TTX, you can use the ttx command in the Terminal:

    ttx [drag&drop .otf/.ttf file here]

    to create an XML representation of the font. This is a file named like the original font but with a .ttx suffix. Search for

    namerecord nameID="5"

    and adjust the value. Then use the same command

    ttx [drag&drop .ttx file here]

    to create a binary font again.

    You can also use FontTools to access font data via FontTools' API, avoiding the XML roundtrip.
  • Karsten, you look strange.
  • Speaking of FontTools, is there any documentation, example or tutorial?
  • Off topic, but I think putting badges as Karsten is kicked off from this forum is not nice.
  • O/T also, but I wonder this: if he has been banned, how is he able to still post?
  • On topic again: I believe it is not a good idea to remove the lib info from the version string because a renderer can adjust its treatment of the font according to the lib version. If I remember correctly, InDesign does recognize a few lib versions and reacts accordingly. I do not remember the details though. Perhaps someone from Adobe can shed light on this. (Is it documented somewhere?)

    So, unless you have a very good reason to remove it, don't.
  • @rainer not discounting that adobe would do something this ridiculous, but it feels a little ie6-ish to leave in these lib strings solely for the purpose of getting better indesign software rendering.

    still, i am slightly skeptical of this rationale only because the last two fonts i purchased, from font bureau and typotheque both have their versions set to something like "Version 1.0" and "Version 1.0; 2009" respectively. what's up with that?
  • Rainer Erich Scheichelbauer
    edited January 2014
    Tools like makeotf and ttfautohint leave their traces in the version string. There should be no issue with removing them these days but you never know. I finally could dig it up: There once was a version of makeotf that created a faulty GSUB lookup type 6, and I believe, software like InDesign 3.0 or later or any other renderer can recognise the faulty table based on the version string, and react accordingly. Therefore, I do not think it is ridiculous to see which compiler created the OT tables. It helps trace bugs. This is also why I do not recommend changing the version string.
  • still, i am slightly skeptical of this rationale only because the last two fonts i purchased, from font bureau and typotheque both have their versions set to something like "Version 1.0" and "Version 1.0; 2009" respectively. what's up with that?
    Are those CFF or TrueType based?
  • they're both cff flavored otfs
  • Those fonts were most likely generated directly from Fontlab and mastered without using the AFKDO's Makeotf.
  • Matthew Butterick
    Matthew Butterick Posts: 143
    edited January 2014
    In Fontlab+Robofab, you can set font.naked().version to a version string, and it will carry through to a font that is generated directly from Fontlab (= will be visible as the version in the info box in the Finder, and in Font Book). IIRC Robofab does not expose this field directly (that's why you have to use naked()). But there are other places version information is stored that you might want to keep consistent:
    font.info.versionMajor
    font.info.versionMinor
    font.naked().tt_version
    I also use the version as part of the font.info.openTypeNameUniqueID.
  • despite the fact that others have implied this is ill-advised, i found this useful and i share it here in case somebody else wants to avoid doing a find/replace (or finds xml.etree interesting).
    """versionit.py - call like `python versionit.py font.ttx vcs_hash'

    it will make a file called font-vcs_hash.ttx
    """
    import sys
    import os
    import xml.etree.ElementTree as ET

    def versionit(ttx_file, vcs_hash):
    ttx_root = ET.parse(ttx_file)
    version = ttx_root.find('CFF/CFFFont/version').get('value')

    for name in ttx_root.findall('name/namerecord[@nameID="5"]'):
    name.text = "Version %s; %s" % (version, vcs_hash)

    filename, extension = os.path.splitext(ttx_file)
    ttx_root.write('%s-%s%s' % (filename, vcs_hash, extension),
    xml_declaration=True, encoding='utf-8')

    if __name__ == '__main__':
    filename = sys.argv[1]
    vcs_hash = sys.argv[2]
    versionit(filename, vcs_hash)
    you can take a font you have generated with the fdk, like foo.otf, and then run ttx foo.otf. From there, you can run it, as below, and you'll get back a foo-hash.ttx file that you can run ttx on, again, to get your new ttf/otf file which has a correctly formatted version string.

    you can feel free to modify this as you see fit (or whatever). much of the code, as you can see, is spent juggling filenames, so you could conceivably work this into some more complex post-processing workflow if that's your thing.