Font Development Best Practices

Technical guidance regarding font development and production

View project onGitHub

3.2 Versioning

A version number in a font is useful in (at least) two situations:

  • Operating systems can know, based on the version number, when to update a package containing a font.
  • If users are having difficulty with a font you have created, they can let you know what version of the font they have, and then you can figure out if the installed version of the font is outdated, or has known problems.

We recommend using a version number in the form of x.yyy (that is, three places past the decimal point). For example, use a version number such as 1.500, not 1.5. This will help the version number to be correctly understood in a variety of environments.

What to use for a version number

You could use a version number based on semantic versioning which has a form of MAJOR.MINOR.PATCH. However, it is not straightforward how the three parts of semantic versioning map to the two parts of a font version. In this discussion Adam Twardoch states he personally uses a font version in the form of M.mpp where

  • M is the major version
  • m is the minor version
  • pp is the patch version

to connect these two concepts. He does not, however, specify what these values might represent in a project. We’ve chosen to use a change in M (major) and m (minor) to reflect significant changes in the functionality of the font and use pp (patch) to indicate both small maintenance fixes (as in 6.301) and work leading up to a major/minor release (such as 6.381, leading up towards 6.400)

Google recommends that the major version value be greater than zero for any fonts that are widely distributed.

Location of the version number and version string

Version information in stored in two locations within a font:

  • head table - a 16.16 decimal number encoded in the fontRevision field.
  • name table - a longer string that can also contain additional information

We recommend that the head and name tables be consistent in the version information represented therein.

The head.fontRevision number may be the only data that operating systems and installation routines use to compare multiple font versions and choose the most recent, so it is important that if two fonts have differences they should have different head.fontRevision values.

The name table version string is text that can contain numbers, letters, and punctuation. We recommend that this string have three parts, separated by spaces, in the form Version M.mpp extrainfo where

  • Version is just the word “Version”
  • M.mpp is the major.minorpatch version number
  • extrainfo is any additional text that may be useful to the user

This extrainfo may be a build number, a test version indicator such as ‘beta3’, a date or time stamp, or any other brief bit of information that can help the user know further information about this particular version. We recommend that developers do not use this additional info as the only indicator that two fonts are different. Only the M.mpp version number should be used to differentiate between versions. Some operating systems show the name table version to users, but may not look at it when comparing font version numbers.

Calculating head.fontRevision

OpenType does not specify the content of the head.fontRevision field, but only that it is a fixed-point number stored with 16 bits before the decimal and 16 bits after. Font vendors have been inconsistent in how they encode a font version in such a numeric field. For example is version 1.1 stored as 0x00010001 or 0x00011999 or even 0x00011000 ?

We recommend the following calculation: Treating the 32 bit fontRevision as two 16 bit integers, calculate them as follows:

  • first 16 bits = M
  • second 16 bits = int( .mpp * 65536 )

Examples of version information:

M mpp head.fontRevision name version string
1 290 0x00014A3d Version 1.290 alpha1
1 295 0x00014B85 Version 1.295 beta1
1 296 0x00014BC6 Version 1.296 beta2
1 300 0x00014CCC Version 1.300
2 101 0x000219DB Version 2.101 build 693
3 560 0x00038F5C Version 2.560 20170329-1
6 101 0x000619DB Version 6.101 FW bundle

Development versions

We recommend that development versions and releases should not share the same version numbers. No two fonts should have the same version number but two different version strings. For example, there should not be two fonts that have version strings Version 1.234 and Version 1.234 beta.

Development versions may have indicators such as alpha or beta in the version string, but that should not be used as the only indicator that two fonts are different. For example, Version 5.678 beta3 means “This font is version 5.678, and by the way, we’re using this version as a third beta test.”. It does not mean “We’re intending to someday release version 5.678, and this is the third beta leading up to that release.”

How to set the version number and version string

In UFO sources the information is held in three keys in fontinfo.plist. FontLab (in the Font Info dialog) and FontForge (go to Element > Font Info > PS Names) have fields for both tables.

By default, Glyphs only provides a way to set the Version major and minor numbers (in the Font Info > Font panel). However there is a way to set the version string in that panel:

  • Click on the + sign next to Custom Parameter
  • Under Property choose versionString
  • Type the version string into the Value field

Here is a summary of where to set version numbers and version strings:

  FontLab Glyphs FontForge UFOv2
head table Complete Version record Version sfnt Version versionMajor, versionMinor
name table TrueType Version record versionString Version openTypeNameVersion