Use Github Release system and SemVer version numbering

179 views
Skip to first unread message

Dave Crossland

unread,
Mar 23, 2015, 3:24:08 PM3/23/15
to googlefontdirectory-discuss

Hi everyone

I suggest using Github's release versioning system - https://www.google.com/search?q=github+releases

I also recommend adopting the www.semver.org version numbering convention

--
Cheers
Dave

WeiH

unread,
Mar 23, 2015, 3:26:56 PM3/23/15
to googlefontdir...@googlegroups.com, da...@lab6.com
How might the following translate to typefaces?

Given a version number MAJOR.MINOR.PATCH, increment the:
  1. MAJOR version when you make incompatible API changes,
  1. MINOR version when you add functionality in a backwards-compatible manner, and
  1. PATCH version when you make backwards-compatible bug fixes.
Additional labels for pre-release and build metadata are available as extensions to the MAJOR.MINOR.PATCH format.

Dave Crossland

unread,
Mar 23, 2015, 3:40:33 PM3/23/15
to googlefontdirectory-discuss

Fonts are sort of "APIs for text."

A MAJOR version would be after a complete redesign. Compare www.google.com/fonts/specimen/Exo and www.google.com/fonts/specimen/Exo+2 - if you have a document using Exo, you don't want to jump into Exo 2, because the 'voice' or 'flavor' -- the feeling evoked -- are (albeit maybe subtly) different.

A MINOR version would be anything that changes the metrics, such as respacing, improving kerning, or making minor corrections to some glyphs - http://c.fastcompany.net/multisite_files/fastcompany/imagecache/inline-large/inline/2014/07/3033126-inline-i-thenewroboto2.jpg from http://www.fastcodesign.com/3033126/roboto-rebooted-why-google-plans-to-update-its-font-like-the-rest-of-its-products - because such updates will cause documents using the font to reflow (albeit subtly in many cases)

A PATCH version would be anything that improves the font without changing the metrics or changes a glyph design in a visible way; 1.0.0 might not have fsType set to 0 or be run through fontcrunch, and changing both those things in a 1.0.1 release won't be visible or reflow anything.
 

Dave Crossland

unread,
Mar 23, 2015, 3:43:16 PM3/23/15
to googlefontdirectory-discuss

Pathum Egodawatta

unread,
Mar 23, 2015, 3:51:25 PM3/23/15
to googlefontdirectory-discuss
So 

- Adding new language support / scripts falls to PATCH? (if metrics stay the same )

On Tue, Mar 24, 2015 at 1:13 AM Dave Crossland <da...@lab6.com> wrote:
--
--
Google Font Directory Discussions
http://groups.google.com/group/googlefontdirectory-discuss

---
You received this message because you are subscribed to the Google Groups "Google Font Directory Discussions" group.
To unsubscribe from this group and stop receiving emails from it, send an email to googlefontdirectory...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Dave Crossland

unread,
Mar 23, 2015, 4:00:31 PM3/23/15
to googlefontdirectory-discuss

On 23 March 2015 at 15:51, Pathum Egodawatta <path...@gmail.com> wrote:
- Adding new language support / scripts falls to PATCH? (if metrics stay the same )

This seems odd to me. The over-arching idea of 'semantic' versioning is to consider the semantics, the meaning, of the changes from one version to another and to increment the appropriate section of the 3 parts of the version number.

With programs, in concrete terms, a patch is usually referring to a small fix in a few lines, while a minor improvement is usually referring to a single larger change or a set of small changes that add up to a larger whole.

With fonts, fixing metadata or imperceptible point adjustment is akin to a patch (and indeed with .sfd/glyphs/ufo files, can be seen clearly as a few lines of text changing.) Adding new languages - eg, adding more diacritic glyphs to a Latin font - is semantically a minor improvement.

Generally a new script requires scaling the Latin, so its the next level up from a MAJOR version increment: an entirely different family name.

Adam Twardoch (List)

unread,
Mar 23, 2015, 4:01:03 PM3/23/15
to googlefontdir...@googlegroups.com
I agree with Dave. 

I'd also say that adding support for one or more new scripts or sognificant number of languages constitutes MAJOR.

Adding just a few or a dozen glyphs to "complete" coverage of a previously intended character set or to add support for just one language is probably MINOR. 

Changes in hinting, in naming or other header things that don't affect the final text layout can be PATCH. 

A.

Sent from my mobile phone.
--

Adam Twardoch (List)

unread,
Mar 23, 2015, 4:10:14 PM3/23/15
to googlefontdir...@googlegroups.com

> Adding new languages - eg, adding more diacritic glyphs to a Latin font - is semantically a minor improvement.

It's not that simple. If you consider how font fallback works in most OSes, then even adding one new character "changes the metrics" because previously, on the same page, that font was rendered using a different font.

But for simplicity's sake, I agree.

> Generally a new script requires scaling the Latin,

Not if I add Cyrillic, Greek, Georgian or other alphabetic scripts.

> so its the next level up from a MAJOR version increment: an entirely different family name.

Then it's a different font. But that depends on your planning and how the project evolves. Sometimes it makes sense to add to an existing font (eg. Cyrillic or Latin), sometimes it's more sensible to start a new font with just that script (and maybe some "scaled Latin" to go with :) ).

A.

Dave Crossland

unread,
Mar 23, 2015, 4:15:35 PM3/23/15
to googlefontdirectory-discuss

--
--
Google Font Directory Discussions
http://groups.google.com/group/googlefontdirectory-discuss

---
You received this message because you are subscribed to the Google Groups "Google Font Directory Discussions" group.
To unsubscribe from this group and stop receiving emails from it, send an email to googlefontdirectory...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.



--
Cheers
Dave

Adam Twardoch (List)

unread,
Mar 23, 2015, 4:25:04 PM3/23/15
to googlefontdir...@googlegroups.com
The semantic versioning poses a problem with fonts, because in OpenType, the head.fontRevision field is traditionally coordinated with the CFF.Version field, and those are traditionally represented as MAJOR.MINOR. There is no place for a "patch" value in SFNT or most font editors. 

My own practice is that I use three-digit MINOR fields where the first digit stands for "proper MINOR" and the other two for PATCH. 

So I'd have 1.000, 1.001, 1.002, 1.100, 1.101, 1.200, 1.201, 1.202, 2.000, 2.001, 2.002, 2.100, 2.101 etc. 

In other words, the font's 1.201 actually means MAJOR 1, MINOR 2, PATCH 1. 

A.

Sent from my mobile phone.
--

Dave Crossland

unread,
Mar 23, 2015, 4:38:28 PM3/23/15
to googlefontdirectory-discuss
On 23 March 2015 at 16:25, Adam Twardoch (List) <list...@twardoch.com> wrote:
The semantic versioning poses a problem with fonts, because in OpenType, the head.fontRevision field

The semver number can be held in the name.version property - https://www.microsoft.com/typography/otspec/name.htm - which is a string type, not a fixed-point number number type

is traditionally coordinated with the CFF.Version field, and those are traditionally represented as MAJOR.MINOR. There is no place for a "patch" value in SFNT or most font editors. 

My own practice is that I use three-digit MINOR fields where the first digit stands for "proper MINOR" and the other two for PATCH. 

So I'd have 1.000, 1.001, 1.002, 1.100, 1.101, 1.200, 1.201, 1.202, 2.000, 2.001, 2.002, 2.100, 2.101 etc. 

In other words, the font's 1.201 actually means MAJOR 1, MINOR 2, PATCH 1. 
 
I see how 1.2.1 maps to 1.201 but how does 1.20.1 map? 1.2001?

Adam Twardoch (List)

unread,
Mar 23, 2015, 5:10:07 PM3/23/15
to googlefontdir...@googlegroups.com
I don't think it's a good idea to have a "semver" version in a name field, and a non-semver version in head.fontRevision+CFF.version. 

Having multiple incompatible version numbers is confusing, and the numerical fields aren't likely to be updated to hold three subfields anytime soon (though it'd be nice). 

It is advisable that each "release" increases head.fontRevision. Effectively, we can only bump MAJOR or MINOR, there is no "PATCH" field.  

So I'm postulating to reduce the versioning to just MAJOR and MINOR due to the format's limitations, and define additional semantics along the lines I proposed.  

I see how 1.2.1 maps to 1.201 but how does 1.20.1 map? 1.2001?

I am making a silent assumption not to have more than 10 "semantically minor" releases. So my 1.20.1 maps to 3.001 :) 

I know it's not perfect but SFNT is almost 30 years old. 

A.

Dave Crossland

unread,
Mar 23, 2015, 5:46:11 PM3/23/15
to googlefontdirectory-discuss

I would rather leave the non name table version numbers static and only increment the name table number on each release.

--

Adam Twardoch (List)

unread,
Mar 23, 2015, 6:12:55 PM3/23/15
to googlefontdir...@googlegroups.com
Dave,

The name id 5 string can contain all sorts of stuff, despite the very precise format prescribed by the OpenType spec (note the use of MUST): 

Version string. Should begin with the syntax 'Version <number>.<number>' (upper case, lower case, or mixed, with a space between “Version” and the number). 
The string must contain a version number of the following form: one or more digits (0-9) of value less than 65,535, followed by a period, followed by one or more digits of value less than 65,535. Any character other than a digit will terminate the minor number. A character such as “;” is helpful to separate different pieces of version information. 
The first such match in the string can be used by installation software to compare font versions. Note that some installers may require the string to start with “Version ”, followed by a version number as above.

The spec does not explicitly forbid a version id 5 field to be formed like: 

Version 1.20.1; ttfautohint xxx

but it also does not give any meaning to the "patch" portion. 

People who repackage fonts (RPM, TeX), font management apps etc. — lots of them rely on either the fact that head.fontRevision differs across releases (because that's pure numerical comparison, so it's fast and easy), or the name id 5 string to be formatted according to the OT spec. Some of them rely on the spec wording to the extent that they stop parsing after the second number. 

I cannot say enough how much I recommend to: 

1. Bump head.fontRevision with every public release
2. Bump name id 5 with every public release
3. Keep head.fontRevision and name id 5 functionalky in sync (so they resolve to the same number)
4. Format name id 5 according to the spec
5. Treating the MAJOR and MINOR version portions as the only significant ones, so either should be bumped with each *public* release. Development, internal or testing versions can have *additional* identifiers such as build numbers,. 

These practices have a 10+-year established tradition. I realize your goal to make font release numbering compatible with the more general software distribution schemes. 

But this should be done with the consideration of the specs, existing implementations and established practices. Or, at the very least, if you propose -- of even recommend! -- breaking or ignoring any of these, a word of clarification as to "why" would be in order. 

And, as usual, I do recommend reading the font format specifications and other relevant technical documentation to anyone who makes fonts. 

Best,
Adam


Sent from my mobile phone.

Pablo Impallari

unread,
Mar 23, 2015, 6:36:14 PM3/23/15
to googlefontdirectory-discuss

Loving these micro-detailed discussions.... sadly the average user dosn't even know that fonts have version numbers.

Dave Crossland

unread,
Mar 23, 2015, 7:11:00 PM3/23/15
to googlefontdirectory-discuss

Adam and I can go on bikeshedding all day :)

Adam you make a solid case that each patch should increment the minor version number and that number should be even in all 3 possible properties.

This is how Roboto is numbered, so, let's try to ask for that

Adam Twardoch (List)

unread,
Mar 23, 2015, 7:54:46 PM3/23/15
to googlefontdir...@googlegroups.com
On 24 Mar 2015, at 00:11, Dave Crossland <da...@lab6.com> wrote:

> Adam and I can go on bikeshedding all day :)

I guess it's a leftover from the years when, as part of FontLab, I was pretty much the only person who tried to make sure that independent font developers make technically-correct fonts that play well with the big boys :)

Also, at MyFonts, my job often is in cleaning up the mess that some foundries have made.

Some of this may seem like bikeshedding, but I believe, while each of the small items may seem unimportant, deviating from good practice in many of them, even in a small scale, rapidly increases the entropy of the entire system to an unmanageable level.

Fonts have a lifecycle with several chain links in which problems can occur. To shield the end-users from as many problems as possible, each of the chain links can be improved: first, the fontmaking tools should be better, second, the font developers should be educated and use good practices, third, font distributors should have tools to clean up the mess, fourth, font consuming apps should have last resort filters (like ot-sanitizer built into browsers). The entropy increases with each chain link, so the earlier in the chain you eliminate the problem, the better.

For many years, the "font technology world" was a pretty closed one, and software that dealt with fonts only dealt with fonts, and with nothing else. But recently, more and more people from other fields (primarily web development, but also software development in general) enter the font tech field.

Sometimes they bring in very valuable ideas and practices, and the GFD is a great example where many processes have been "standardized anew", i.e. internal font tech-specific practices were replaced by more general ones. Switching to Github, working towards fonts buildable from sources using "make" etc. are all good examples of that.

I am extremely open to this process, largely because I remember those earlier years where "the shit was largely on me" (and a handful other people). The more practices and tools we adopt from the "wide software development world", the better.

But having worked for years with font developers and software makers both large and small, I know that this road is full of caveats. I don't want to stick to old rules for the sake of it, but I also don't want to jump to new waters only because they're shiny :)

And specifically to the point: version numbers are not that relevant for the end-users, and they shouldn't be. With things like the iOS App Store, the Mac App Store or the Adobe Creative Cloud, with automatic updating systems etc., users shouldn't really care about version numbers anymore — because it should be the software that keeps their assets (including fonts) up-to-date.

But computer programs have stricter expectations on things like version numbering than people.

For computer programs, the easiest process is to compare two numbers. Which is why I believe that in OpenType fonts, the head.fontRevision field (which is just one number internally, though traditionally split into two parts for "major" and "minor") should be the key place to put versioning information, and all the other fields should be secondary. That's because the head.fontRevision field is the field that auto-update apps should be able to use reliably to decide whether "old version" should be replaced by a "new one". So that the end-user doesn't have to care.

Cheers,
Adam


Dave Crossland

unread,
Mar 23, 2015, 8:06:19 PM3/23/15
to googlefontdirectory-discuss

Thanks for the context!! I'm all agreed.

Back to the color of this BBB bikeshed though :)

The head.dateModified string can be used to mitigate the ambiguity of concatenation of a second period segmented patch number with the minor number.

Reply all
Reply to author
Forward
0 new messages