My last post was about adding lots and lots of alternates to my Protest™ font in FontLab VI.

This time I’m writing about adding OpenType features to Protest. This includes stuff like language support and cycling through alternates. I’m only going to cover a portion of the OT features in this post, because there’s a lot. I’ll cover more in future posts as I learn. I’ve learned a ton these last few weeks, but the more I learn, the more I realize I don’t know.

I now have over 1300 glyphs in my Protest font. It’s getting to feel like I’ve built a giant castle out of blocks, each stacked neatly and arranged just so. The more glyphs I add, the bigger and more glorious my structure… and the more precarious it feels.

There are just so many moving parts at this point, it’s difficult to hold them all in my head. Getting into the OpenType features is like a mental juggling routine. What do I need to do with this language? How do I handle this situation? What classes do I need? Aaaaargh!

I need to take a deep breath, and remember to take each piece one at a time.

What are OpenType features?

OpenType features are what allow certain aspects of a font’s usage to be automated for the user. There are two kinds: substitution and position. Substitution replaces a glyph or glyphs with another glyph or glyphs. Position moves and/or spaces a glyph or glyphs.

Helpful Reading

Tal Leming wrote a tutorial called The OpenType Cookbook. I’ve found this tutorial to be incredibly helpful. One of the ways it’s been most helpful to me is the way in which he has broken everything down. Go read it. Seriously. But come back for specifics not covered in the tutorial.

OpenType Cookbook is super extra helpful, but by no means comprehensive. It gives a great foundation for writing OpenType features, and gives some good examples, but it’s not meant to cover every situation. For the specifics of Protest I need to go hunting for information.

I also need to know how to use FontLab VI to do what I need. Tal’s cookbook doesn’t assume a particular editing environment. Also, there are a number of features referenced in other articles I’ve read that are specific to other font software. So I need to know what FontLab VI can do. Thankfully, they have very thorough documentation.

Helpful FontLab VI documentation (IL;PR*):

Okay. It’s time to jump in.

Feature File Structure

The OpenType features are written into a feature file (.fea extension). Taken as a whole, these features are executed in order, and order is important.

A feature file should have this structure according to Tal Leming:

  1. languagesystem declarations
  2. global classes
  3. all substitution features
  4. all positioning features

In this post I will cover 1, 2, and introduce 3.

Language Systems

Before anything else in my features, I need to declare which language systems my font will cover or have special cases for. In FontLab VI, this is done in the Features Panel under the “Prefix” section. There are default comments (preceded by hash marks) indicating where things should go. In this case under “Language system declarations” at line 18.

Every font needs to have the default declaration:
languagesystem DFLT dflt;

Next, since my font uses the latin script, “latn” needs to be declared as a script with the default language:
languagesystem latn dflt;

Then, I need to declare any special cases for which I’ll be writing lookups. For Protest, these include Catalan (for the geminated L, or “punt volat”); Dutch (for the ij acute); German (for the uppercase eszett); Moldovan and Romanian (for the S with comma accent); and Azeri, Kazakh, Tartar, Crimean Tartar, and Turkish (for the i with dot accent).

Each of these languages has a specific three letter code, or language system tag. Microsoft has a convenient list of all the language system tags.

So the declarations for Protest look like this:

languagesystem DFLT dflt;
languagesystem latn dflt;
languagesystem latn AZE;    # Azeri
languagesystem latn CAT;    # Catalan
languagesystem latn CRT;    # Crimean Tartar
languagesystem latn NLD;    # Dutch
languagesystem latn DEU;    # German
languagesystem latn KAZ;    # Kazakh
languagesystem latn MOL;    # Moldovan
languagesystem latn ROM;    # Romanian
languagesystem latn TAT;    # Tartar
languagesystem latn TRK;    # Turkish


Classes are sets of glyphs, but you already knew that because you read Tal’s tutorial.

If I were writing my own feature file document, this is where I’d put the class declarations. Since I’m using FontLab, I can select glyphs to add to a class in the Classes Panel.

At this point, I didn’t just up and make all my classes. I had to start writing my features to see what classes I’d need, and then created them as I went. With the Classes Panel, all of my class declarations are right where they should be.


This is where the magic happens. Features are the sets of lookups comprised of individual rules that make an OpenType font do things.

This is what the feature order should be according to Tal Leming:

  1. script language specific forms (locl)
  2. fractions (frac, numr, dnom)
  3. superscript and subscript (sups, subs)
  4. figures (lnum, onum, pnum, tnum)
  5. ordinals (ordn)
  6. small caps (smcp, c2sc)
  7. all caps (case)
  8. various alternates (calt, salt, ss01, ss02, ss…)
  9. ligatures (liga, dlig)
  10. manual alternate access (aalt)
  11. capital spacing (cpsp)

The crossed out features are ones I’m not including. (Woot! Four down, seven to go!)

Features aren’t something I can just make up. Each one is four letters, and registered for implementation by software developers. Microsoft Typography documentation is a good place to reference all of the registered features to find out what they’re supposed to contain. If there’s something a font needs to do that isn’t in my blog posts, then it probably lies under the purview of one of the registered features listed on the Microsoft site.

Up Next

In the next post I’ll dive into the specifics of the substitution features, starting with the locl feature.

  • Part 2: locl
  • Part 3: frac, ordn, case, liga, dlig.
  • Part 4: calt, aalt
  • Part 5: mark, mkmk
  • Kerning!


*IL;PR = It’s long; please read. (Back to reference)