Kerning Pairs Part I

I was listening to Mac Power Users 128. The guest had an interesting comment on designing a typeface and how good designers adjust the kerning for every pair of letters in the language. In the english language, there are 6.15611958020716E36 (26^26) possible pairs of lower case letters alone. I’m thinking that’s not happening.

So I wrote a quick little Java program to count all pairs of letters seen in the standard dictionary on my Mac. I filtered out all words that contained non letters and lowercased all characters. The dictionary contains 235886 words and the program comes up with 609 unique pairs of characters. Now I’m thinking we’re in the realm of reasonable.

Presumably a typeface designer will pick the top X pairs to adjust and leave the remainder at the default kerning. The 609 pairs doesn’t consider any capitalization. If any dictionary word can be at the start of a sentence, 342 pairs are added.

The top 10 pairs of characters are

  1. ti 31517
  2. er 31480
  3. in 31201
  4. at 26675
  5. en 23654
  6. ri 22994
  7. ra 22790
  8. ro 22195
  9. an 22063
  10. re 21966

The files containing the pairs are KP, sorted alphabetically, and KPn, sorted numerically by frequency.

import java.util.Map;
import java.util.Scanner;
import java.util.TreeMap;

public class KerningPairs {

private static final Map PAIRS_FREQ = new TreeMap();
private static final int STRING_LENGTH = 2;

private static void addPair(final String substring) {
Integer count = Integer.valueOf(0);
if (KerningPairs.PAIRS_FREQ.containsKey(substring)) {
count = KerningPairs.PAIRS_FREQ.get(substring);
KerningPairs.PAIRS_FREQ.put(substring, count + 1);

public static void main(final String[] args) throws IOException {
final FileReader fileReader = new FileReader("/usr/share/dict/words");
final Scanner scanner = new Scanner(fileReader);

while (scanner.hasNext()) {
final String line =;
if (line.matches("\\p{Alpha}{2,}")) {
final String lcLine = line.toLowerCase();
for (int i = 0; i < (lcLine.length() - KerningPairs.STRING_LENGTH); i++) { final String substring = lcLine.substring(i, i + KerningPairs.STRING_LENGTH); KerningPairs.addPair(substring); } } } for (final String pair : KerningPairs.PAIRS_FREQ.keySet()) { System.out.println(pair + "\t" + KerningPairs.PAIRS_FREQ.get(pair)); } fileReader.close(); } }

This entry was posted in Tech and tagged . Bookmark the permalink.