Skip to content

Context Kerning

OK, so you’ve bled your heart and soul out into the kerning.

You’ve made exceptions.

How can you still not be done yet!!??

Context Kerning is the final icing on the kerning cake.

Problems in Kerning

Here’s some work from designers I admire and respect. It’s hard to get kerning and spacing right, there’s just so much of it! Kerning shown as is.

Some of these things can only be fixed with contextual kerning. (Well, the last example is actually spacing gone wrong.)

These are combos that make font designers look bad.

Suppose you are just some graphic designer then you check out that period between a seven and nine.

“These font designers don’t know how to center a dot!”

I would say, “Centering dots is my bread and butter, baby!”

Anyways, you and I know it’s because kerning messes up some triples.

But what designers see is a bunch of crosseyed font designers, with glasses five inches thick.

If you don’t like these triples, you have two basic options:

  1. Kern Loose
  2. Context Kern

If you actually kern the punctuation with the numbers or letters, unless it is very loose, you will need to do context kerning to get good results. :/

Most people won’t see these, so it just depends upon how you want to do things.

What Context Kern Can Do For You

Context kern can allow you to fix crashes like L’A. Or it can help you even out the placement of periods, such as between 7 and 9.

It gives your spacing that final polish!

I know of a Spanish graphic designer who uses GREPs in inDesign to context kern the ‘y’ and the space. ‘y’ causes many gaps within Spanish text. Hopefully some of our work will save our customer’s time.

How to Context Kern on Single Master Family

Context kerning is manual.

It’s with code—but it’s very, very basic code.

Here’s an example line of code and description.▼

Step 1: Add Lookup

We’ll add a “prefix lookup” since that will be easier for us to move around.

Substeps:

❶ Open Features Panel.

❷ click the Prefix at the top. Scroll down to the bottom of the prefix.

❸ Paste this:

lookup contextKern{ pos L' 50 quotesingle' 50 A; }contextKern;

❹ Now that you’ve pasted that in the prefix, we have to reference it somewhere.

We will reference that in the feature, calt (contextual alternates).

You put it here, because most programs have calt on by default. Putting it here allows you to preview your context kerning. (Which you couldn’t do if you built this out.)

If you don’t have calt, push the plus sign in the features panel. Select the calt feature or say other feature and type the name manually.

Inside calt, paste: lookup contextKern;

Calt will reference our lookup from the prefix.

❺ Push the play triangle at the top of features. Test out in the Preview panel.▼

Nice!

These are not our final values. We’re just testing.

Before we enter the values, we need to add classes.

Step 2: Add Classes

Here we are going to add our kerning classes into our prefix.

❶ In the features panel, add classes by clicking on the hamburger, and then go down to Import Classes and Tags. ❷ Now into your prefix, modifying your classes to be correct.

lookup contextKern { pos @L' 50 quotesingle' 50 @A1; } contextKern;

Of course, use your specific kerning class names.

Info

I didn’t use the @quotesingle class, since it contained my quotedbl. Quotedbl is usually not included in the context kerns because it is wider.

❸ Turn calt on and off in the Preview panel to make sure that this works. Include other members of your class. Test in the Preview panel to make sure that this still works.

If it worked, great!

If not, this is what you do.

If Kerning Classes Didn’t Work

Optimally, you would use your kerning classes. If these classes don’t work, you can create OpenType classes.

One example: you could use a name like APos and APos1, to let yourself know that these classes are for positioning only.

Step 3: Context Kern

Download some of my tests.

Turn calt on and off in the Preview panel and your metrics window sidebar to make sure it is changing the spacing as you intend.

Before you entirely context kern, get to the end of this tutorial, especially export to make sure it works right.

Step 4: Build Kern Feature

1) Kerning should be done before we build the feature. 2) Or you can build it just to test your context kerning at first.

Add kern feature In the Kerning panel, at the bottom of your features list (sidebar), push the +. Add empty feature. In the feature name, type “kern”. ❷ Populate kern feature Now push the star to add all of your kerning into this feature. ❸ Reference the contextKern lookup. lookup contextKern;

I put mine here.

It’s outside of the automatically generated code, but still within the kern feature.

Calt is no longer necessary. You can delete that feature if you are done context kerning.

Step 5: Test

To test my file, I did something outlandish like add 500 space in between each of the letters.

My context kerns worked! I hope yours did too.

That’s it!

Info

If you get a kern table overflow problem, I’m not sure what you would do. That’s for more technical people to answer!

How to Context Kern for a Multiple Master Family

Follow the same steps as above.

Warning

  1. You can only have one context kern shared for all masters. For example, if you do pos @L’ 50 quotesingle’ 50 @A1; this will apply to the hairline and black alike. So that means you have to plan kerning wisely.
  2. The same kern feature will show up in all masters. However, the real kerning will get put into the export.

FontLab does a brilliant job of putting all this together.

It puts table sub breaks as needed. If you context kern too much, FontLab will let you know if there is a table overflow and you can revise your context kerning.

Besides, FontLab organizes everything in an efficient way.

It’s also more confusing for someone to duplicate your code.

Here’s an example of part of the exported context kerning from one of my fonts:

pos [T Tcaron Tcommaaccent Tcedilla]' lookup kern_19 [period period.ss03 perioduc perioduc.ss03]' lookup kern_36 V; pos V' lookup kern_30 [period period.ss03 perioduc perioduc.ss03]' lookup kern_34 [T Tcaron Tcommaaccent Tcedilla]; pos [T Tcaron Tcommaaccent Tcedilla]' lookup kern_18 [period period.ss03 perioduc perioduc.ss03]' lookup kern_35 [W Wdieresis Wcircumflex Wgrave Wacute]; pos [W Wdieresis Wcircumflex Wgrave Wacute]' lookup kern_31 [period period.ss03 perioduc perioduc.ss03]' lookup kern_35 [T Tcaron Tcommaaccent Tcedilla]; pos [T Tcaron Tcommaaccent Tcedilla]' lookup kern_17 [period period.ss03 perioduc perioduc.ss03]' lookup kern_34 @kern2; pos @kern2' lookup kern_16 [period period.ss03 perioduc perioduc.ss03]' lookup kern_34 [T Tcaron Tcommaaccent Tcedilla]; pos V' lookup kern_30 [period period.ss03 perioduc perioduc.ss03]' lookup kern_34 V; pos V' lookup kern_29 [period period.ss03 perioduc perioduc.ss03]' lookup kern_35 [W Wdieresis Wcircumflex Wgrave Wacute]; pos [W Wdieresis Wcircumflex Wgrave Wacute]' lookup kern_31 [period period.ss03 perioduc perioduc.ss03]' lookup kern_35 V; pos V' lookup kern_28 [period period.ss03 perioduc perioduc.ss03]' lookup kern_31 @kern2; pos @kern2' lookup kern_15 [period period.ss03 perioduc perioduc.ss03]' lookup kern_31 V; pos [W Wdieresis Wcircumflex Wgrave Wacute]' lookup kern_31 [period period.ss03 perioduc perioduc.ss03]' lookup kern_35 [W Wdieresis Wcircumflex Wgrave Wacute]; pos [W Wdieresis Wcircumflex Wgrave Wacute]' lookup kern_30 [period period.ss03 perioduc perioduc.ss03]' lookup kern_36 @kern2; pos @kern2' lookup kern_17 [period period.ss03 perioduc perioduc.ss03]' lookup kern_36 [W Wdieresis Wcircumflex Wgrave Wacute]; pos @kern2' lookup kern_16 [period period.ss03 perioduc perioduc.ss03]' lookup kern_34 @kern2; pos @kern40 [period period.ss03 perioduc perioduc.ss03]' lookup kern_26 [T Tcaron Tcommaaccent Tcedilla]; pos @kern40 [period period.ss03 perioduc perioduc.ss03]' lookup kern_26 V; pos @kern40 [period period.ss03 perioduc perioduc.ss03]' lookup kern_25 [W Wdieresis Wcircumflex Wgrave Wacute]; pos @kern40 [period period.ss03 perioduc perioduc.ss03]' lookup kern_26 @kern2; pos L' lookup kern_33 quotesingle' lookup kern_33 A; pos A' lookup kern_26 space' lookup kern_37 A;

It’s like, yes someone could put it together. But they’d have to find the relevant rules inside each lookup.

So this would be a deterrent, because it wouldn’t be worth the effort for someone to steal your code.

Good work!!!

You are finally done with kerning!!

Dave Lawrence California Type Foundry