Skip to main content

FontCreator Tutorials

Creating Handwritten Fonts with Contextual Alternates

written by Erwin Denissen, published September 18, 2024

Introduction

  • Why Handwritten Fonts?
    • Handwritten fonts offer a personalized, organic feel, making them ideal for creative projects. But to avoid the mechanical look of repeating glyphs, we can introduce OpenType layout features to replace the first and last letter of a word and swap other letters with pseudo-random alternatives.
  • What We’ll Cover
    • How to replace first and last letters with contextual alternates.
    • How to create pseudo-random alternates for letters within words.
    • A deep dive into using the calt feature to make these substitutions.

    Understanding OpenType Layout Features

    • Why Contextual Substitutes Matter

      • Contextual substitutions enhance the visual variety of a handwritten font by providing alternate versions of glyphs based on their position in a word.
    • Challenges with Text Shaping Engines

      • Detecting word boundaries and how shaping engines process text can be tricky, but we’ll provide a solution that works across all software supporting OpenType layout features.

    Step 1: Preparing the Font for Substitutions

    • Create Alternate Glyphs
      • For each letter, prepare alternate glyphs for word-initial, word-final, and middle positions. Additionally, you can create multiple alternates for random substitution.
    • Naming Your Glyphs
      • Use clear naming conventions for your alternate glyphs: a.start, a.between1, a.between2, a.end for start, the two between, and end versions, respectively.

    Step 2: Implementing the OpenType Features

    • Introducing the calt Feature

      • The calt (contextual alternates) feature is key to making contextual substitutions happen. We'll set up lookup tables to identify word boundaries and substitute the appropriate glyphs.
    • Feature Code Breakdown:

      • In FontCreator, go to the OpenType Designer, and click the Code Editor button at the bottom and replace the exisitng code (or merge it) with this fea code:
      ###
      # OpenType Layout feature definitions
      # Format: OpenType Feature File Specification version 1.25.1
      # Generated by: FontCreator
      #
      
      languagesystem latn dflt; # Latin default
      
      @letter = [a-z];
      @letter.start = [a.start];
      @letter.between1 = [a.between1];
      @letter.between2 = [a.between2];
      @letter.end = [a.end];
      
      lookup SingleSubstitutionEnd { # GSUB lookup type SingleSubstitution
          sub @letter by @letter.end;
      } SingleSubstitutionEnd;
      
      lookup SingleSubstitutionBetween { # GSUB lookup type SingleSubstitution
          sub @letter by @letter.between1;
      } SingleSubstitutionBetween;
      
      lookup SingleSubstitutionStart { # GSUB lookup type SingleSubstitution
          sub @letter by @letter.start;
      } SingleSubstitutionStart;
      
      lookup SingleSubstitution1 { # GSUB lookup type SingleSubstitution
          sub @letter.between1 by @letter.between2;
      } SingleSubstitution1;
      
      feature calt { # Contextual Alternates
          lookup ChainingContextStart { # GSUB lookup type ChainingContext
              ignore sub @letter.start @letter';
              ignore sub @letter.between1 @letter';
              ignore sub @letter @letter';
              sub @letter' lookup SingleSubstitutionStart @letter;
          } ChainingContextStart;
      
          lookup ChainingContextBetween { # GSUB lookup type ChainingContext
              sub @letter.start @letter' lookup SingleSubstitutionBetween @letter;
              sub @letter.between1 @letter' lookup SingleSubstitutionBetween @letter;
          } ChainingContextBetween;
      
          lookup ChainingContextEnd { # GSUB lookup type ChainingContext
              ignore sub @letter' @letter;
              sub @letter.start @letter' lookup SingleSubstitutionEnd;
              sub @letter.between1 @letter' lookup SingleSubstitutionEnd;
          } ChainingContextEnd;
      
          lookup ChainingContextRotate { # GSUB lookup type ChainingContext
              sub @letter.between1 @letter.between1' lookup SingleSubstitution1;
          } ChainingContextRotate;
      } calt;

      Step 3: Testing and Refining Your Font

      • Testing in FontCreator
        • Use FontCreator’s preview features to test the contextual substitutions in various contexts.
      • Ensure Compatibility
        • Make sure your font works across a variety of software that supports OpenType features, like Adobe software, Microsoft Word, and web browsers.

      Conclusion

      • Summing Up
        • Designing handwritten fonts with OpenType layout features adds complexity, but the results can make a font feel much more dynamic and unique.
      • Next Steps
        • Once you've mastered contextual alternates, consider adding more advanced OpenType features like ligatures or stylistic sets.