Creating Fonts with Complex Outlines

  • by Rainer Erich Scheichelbauer
  • Tutorial

Modern font technology is primarily geared towards ‘normal’ typefaces. That means that some of the technologies in use assume that your font:

  • has simple outlines with the smallest possible number of nodes
  • has nodes at extremes (learn more about drawing good paths)
  • has multiple glyphs that share similar shapes (e.g., the shoulders of lowercase n, h and m are close to identical)
  • has a reasonable number of glyphs (for the most part, a three- to four-digit number)

Now, if your font breaks any of these assumptions, we are talking about so-called ‘complex’ outlines. If your font sports these kinds of outlines, you may have to take decisions on subroutinization, hinting, and possibly even adjust your paths. Otherwise your font may not export, or worse, it does export and ships and performs badly for your end users, and you will receive loads of support mails. Not good.

To give you an idea what complex outlines can look like:

Typefaces: Adinah by Andy Lethbridge, Fairwater by Laura Worthington, Letterpress by Marcus Sterz, Weingut by Georg Herold-Wildfellner


Subroutinization is a filesize-saving mechanism in CFF fonts (i.e., fonts containing PostScript outlines, suffix: .otf) that tries to find recurring structures in your outlines and stores them in so-called subroutines, hence the name. It works a little bit like components, but also with paths and curves, not just whole glyphs. And it is done automatically at export time, so you usually do not have to worry about it.

Subroutinization works best if you have many similar shapes in your fonts, and your font has a regular size, like a couple of hundred, perhaps a few thousand glyphs. It reaches its limits if you have too many different shapes, like in grunge or scan fonts. Or if you have very complex or detailed outlines, or a very high number of nodes per glyph. Or, as in many CJK fonts, if you have very many glyphs in your font, say 20,000 or even more. (Want to know more? Read Ken Lunde’s blogpost about subroutinization in CJK fonts.) If any of these are the case, you will notice that exporting takes unusually long. That is the subroutinization algorithm trying to find similar shapes in millions and billions of outlines. It can happen that the subroutines make the font larger, not smaller, because shapes are found in high numbers, but reused only very little. It can even happen that the font does not export at all.

The Disable Subroutines parameter turns subroutinization off. Go through the respective instances in File > Font Info > Instances, and in each instance’s Custom Parameters table, add a new parameter with the plus button, switch its Property to Disable Subroutines, and turn on the checkbox that appears under Value:

Consider disabling subroutinization:

  • in fonts with very many glyphs, a few thousand and more,
  • in fonts with non-similar shapes, like grunge, handwriting, letterpress, or ransom-note fonts, where the whole point is that the glyphs look as different as possible,
  • in fonts with highly detailed outlines, like drop caps, symbols, icons, illustrations, dingbats,
  • in fonts with a high node count per glyph, starting at three-digit numbers.


Hinting is the process of putting hints on the outline parts. Hints help the rasterizer determine which parts of a glyph are essential stems and need to be maintained or normalized during grid-fitting. Grid-fitting is the process of distorting outlines so they better fit onto the pixel grid.

Yes, you read that right. Hinting does not preserve your shapes, on the contrary, it distorts them. Hinting sacrifices shape fidelity for the higher good of a better fit at small pixel sizes. The result is a cleaner, crisper, more unified, more legible text on the screen. Hinting poses a lot of requirements on your outlines, though: they have to be as clean and ‘normal’ as possible.

Consider no hinting:

  • in fonts with intentionally inconsistent, heterogeneous, non-similar shapes,
  • in connecting script fonts where the outstroke of one letter has to precisely meet the instroke of the following letter,
  • in fonts with highly detailed outlines,
  • in fonts with a high node count per glyph,
  • in fonts without alignment zones in File > Font Info > Masters,
  • in fonts without standard stem definitions in File > Font Info > Masters,
  • in fonts with non-normal outlines that:
    • do not have nodes at extremes
    • show dissimilar, heterogeneous stem thicknesses
    • do not consistently reach into alignment zones
    • have been created with decorative effects such as the Glyphs filters Roughen or Hatch Outline would create, but also inlines, outlines, dotted lines, shadows, 3D effects, etc.

To avoid hints in your font, you have to do two things: disable autohinting and remove manually placed hints. To get rid of autohinting, simply disable the Autohint option in the File > Export dialog. Or, use the Autohint custom parameter in File > Font Info > Instances with the Value off, of course:

To get rid of already placed manual hints any a font, you can click on the gear button in the lower left corner of the Font view, choose Add Smart Filter. In the upcoming dialog, give your Smart Filter a name that makes sense to you, and set it to Has Hints: Yes. Confirm the dialog by pressing OK and select the Smart Filter in the left sidebar. Then go through the glyphs and delete the hints manually.

Or, more easily, there are scripts for deleting manual hints. In my mekkablue Scripts repository on GitHub, you will find Hinting > Delete all Hints in Font, among others. Find installation instructions in the readme of the repository.

To make sure that no hints made their way into the resulting OpenType font, you should test your fonts. Open the exported OTF in Glyphs and apply the Smart Filter we discussed a few paragraphs ago. Or, step through your glyphs in apps like DTL OTMaster.


We have discussed complex paths, i.e., paths with a high amount of nodes. Assume you have complex outlines in your design, and being the good citizen that you are, you have disabled subroutinization and hinting as suggested by your local font authorities. Still, there may be problems, because a high amount of small curve segments can be problematic in CFF-based OTFs.

Firstly, while such a font may work on the screen, a printer may easily yield a Too many subpaths error. When rasterizing, each little curve segment is broken into many small line segments, so-called ‘subpaths’. They are really small, well below the threshold of the rasterizing resolution. On a laser printer, this resolution may be relatively high, meaning that the subpaths have to be very short, and of course, very many, since they have to add up to the complete curve segment they are supposed to be replacing. To give you an idea, this is a zoomed-in view of a curve segment broken into loads of subpaths:

Secondly, you may run into performance problems when using the font in Microsoft Windows. Like, you type a word of six letters, and then, you are watching the letters appear one after another for another ten seconds or so. Windows has troubles with CFF outlines in the first place already, but complex CFFs can be a bridge too far for the operating system from our good friends in Redmond.

Two ways to deal with the issue:

Firstly, if your design allows it, replace all your curve segments with straight segments. The rationale behind this solution is that a line segment is significantly easier to render than a curve segment.

There is a plugin that does that for you: Retractor. Find and install it via Window > Plugin Manager. You can trigger it automatically at export time with a Filter custom parameter (more info in the Filter readme). This is usually recommended for fonts with very small curve segments, such as grunge fonts, dirty fonts, letterpress fonts.

If you do have bigger curve segments in your outlines, you may consider the use of the Roughen filter (Filter > Roughen), which turns everything into little line segments. Consider small displacement values, perhaps even zero, but slightly larger Segment Length. Again, you can trigger this filter through a custom parameter, which you can simply copy into your clipboard through the gear menu in the lower left corner of the filter window, and subsequently paste into the Custom Parameters table in File > Font Info > Instances.

Secondly, if your design requires the curve segments to stay in place cleanly, consider exporting the font with TrueType outlines. Here, the idea is that TrueType actually allows higher complexity than CFF/PostScript does. To export your font as TrueType, you can switch on the Save as TTF option in File > Export, or use the Save as TrueType custom parameter in File > Font Info > Instances. It’s that easy.