TrueType autohinting is an easy and effective way to improve the on-screen legibility of your font on Windows.
First the boring part. If you have been through this before, feel free to skip to the next headline.
What is hinting?
One popular myth amongst type designers is that hinting was about ‘preserving your shapes on the screen’. In fact, the opposite is true. Hinting does not preserve your shapes, it distorts them so they better fit the pixel grid of your output device, typically, but not necessarily, a screen. The distortion will be greater the lower the resolution of your output device is. But it can be effective up to and beyond a size of 80 pixels, which is equivalent to a font size of 19 points on a 300 dpi printer.
Plus, hinting only works if your type design fulfils certain requirements. Hinting only really makes sense if your font is intended for legibility at small sizes and as ‘normal’ a design as possible. In other words: if legibility is more important than shape precision. Display fonts, cursive script fonts, grunge fonts, icon fonts and the like are better off without hinting. If you are doing one of those, forget hinting altogether, skip this tutorial and read ‘Creating fonts with complex outlines’ instead.
For hinting to work, your paths need to have extremum points and consistent design features, like similar heights and overshoots, stem widths as consistent as possible, etc. So ask yourself: does your design need hinting at all? And if yes, do its paths support hinting? If your answer is yes, keep on reading.
Export with ttfautohint
To make use of TrueType autohinting, you can simply just export your fonts with the Autohint option on, and in the TrueType outline flavor:
That’s it. Glyphs will pass the font to the ttfautohint algorithm, which in turn will analyze the structure of your shapes and make an informed guess about the hints it will put in your font.
Please keep in mind:
- Contrary to the situation we have in PostScript hinting, TrueType autohinting is not compatible with manual TT hints, so you need to decide which one you want. When you switch on Autohint for a TTF export, the manual hints will be ignored. (Likewise, if you export without Autohint, all ttfautohint settings will be ignored.)
- In its current state, ttfautohint is not compatible with the Variable Font export. So everything you read in this tutorial applies to static TTF exports only.
What happens when you export is that ttfautohint smartly measures a number of key glyphs in your font, and inserts TrueType hints (a.k.a. instructions) based on its findings. With a little luck, your TTF looks good on Windows already. Let’s find out.
For testing your hinting results, you will need Windows. As a Mac user, you may want to look into virtualization solutions like Parallels or VirtualBox.
Hinting information embedded in the font is, for the largest part at least, ignored on the Mac. That is because macOS does its own autohinting on the fly when you install the font. In a nutshell, this is the dreaded macOS font cache.
In their interpretation of TT hints, other platforms are… shall we say, rather unpredictable. Sometimes they are taken as they are, sometimes they are partially interpreted, sometimes they are (like on the Mac) replaced by on-board hinting. Sometimes this changes from one version of the OS to the next. If you need to cater to these platforms, try to find out first if TT hints have any effect at all on the screen rendering, and if yes, come up with a testing scheme.
Back to our beloved Windows. Typically, there are two setups you will want to test: Microsoft Word, and a Chromium-based web browser like Microsoft Edge or Google Chrome. That is because Word indeed renders type differently than the default renderer built into Windows. You may ignore one or the other depending on your (or your client’s) intended use of the fonts.
Use screen zoom
First, set up screen zoom in System Preferences > Accessibility:
It is a good idea to set up a scroll gesture or good shortcuts for quickly enlarging the pixel image so you can check on the hinting result. While you are in this Window, click on Advanced… and disable Smooth images:
What this option does is it blurs the pixels. And it is a default setting, huh. Why anybody would ever want that, I do not know. We certainly do not need it for verifying the bitmap rendering. So uncheck that checkbox and confirm the dialog and your pixels will not be blurry.
No Retina for Windows
If you have a Retina display, make sure the Windows screen resolution stays low. After all, you want to see the pixels. Hinting will not have much visible effect in hi-res setups. Perhaps your virtualization software has a setting that allows to stretch a Windows pixel over 2×2 Mac pixels.
Set up a test document in Word. The mekkablue script Test > Copy Word Test Text puts a complete character set for the frontmost font in your clipboard, so you can paste it in an empty Word document.
Set up a test HTML for Edge or Chrome: you can use the mekkablue script Test > Webfont Test HTML, it will create an HTML for the current font in the latest export destination. Or a type tester website like Viktor Nuebel’s FontDrop. Zoom in with your scroll gesture or shortcut, so you can examine the pixel structure in all its pixelated glory, like this:
Zoom in, test in various sizes, best in a multiple-size waterfall, check for consistency in stem weight and consistency in heights such as baseline, x-height, cap height, etc. Subsequently focus on groups of glyphs that should appear consistent with each other, e.g., all uppercase, all lowercase, all lining figures, all small caps, you name it.
If everything looks consistent, you’re done and can go for lunch, and even skip the rest of this tutorial. Bon appétit.
If only a few glyphs are affected by inconsistencies such as dancing heights or irregular stems, chances are that something is wrong in the paths. Check path direction, extremum points, whether point coordinates are rounded, and whether the points that are close to vertical metrics really align with them or at least have a consistent overshoot. There are many plug-ins and scripts that help you with that.
If many glyphs are affected, overriding the default settings of ttfautohint may help. Read on.
For each instance in Font Info > Exports, add a custom parameter called TTFAutohint options. Note that you can select multiple instances, and add the parameter in one go for all of them:
Once the custom parameter is added, click on its value to open the dialog, and go through the settings. Again, you can batch-edit the options in more than one instance at a time:
The listing below contains all the options with a direct link to their respective ttfautohint documentation, and a short summary of that documentation. Where it says ‘Advice’, I added my own suggestions for the setting in question.
Hint Set Range: the PPM range for which the instructions will be optimized.
Advice: large ranges can cause huge file sizes, so keep it just to the most relevant PPM sizes for webfonts. Optimization typically does not make sense below 12 PPM and above 40 PPM. Hints will apply beyond that range (see Hinting Limit below), it is just that the bitmap optimization focuses on these sizes.
Default Script: default script for OpenType features.
Advice: ignore or pick the main script the font was developed for. If you have many glyphs that are accessible through OT features, pick the script that represents most of those. The hinting will be more consistent within one script.
Fallback Script: default script for glyphs that can’t be mapped to a script automatically.
Advice: best to pick the main script the font is intended for.
Hinting Limit: the PPM size where hinting gets switched off. Default is 200 pixels, must be larger than the maximum of the hint set range. Pixel sizes up to this size use the hinting configuration for the Hint Set Range maximum (see above).
Advice: pick a sensible font size up to which the font can be expected to be used on-screen. Values below 100 are OK too. Consider adding 1 PPM for safety. In order to cover sizes up to 80, try 81 if you do not get the desired result.
Fallback Stem Width: the stem width value for all scripts that lack proper standard characters in the font. The value is in font units and must be a positive integer. Default is hard-coded to UPM×50÷2048 units. For symbol fonts, you also need to specify a Fallback Script (see above).
Advice: for each instance individually (do not batch-set), horizontally measure the width of a representative glyph for the script, e.g., the
idotlessin Latin, and enter that stem width here. By reducing or increasing Fallback Stem Width, you can make the overall appearance of your font darker or brighter, respectively.
x-Height Increase Limit: from this pixel size down to 6 PPM, the x-height is more likely to be rounded up. Default is 14 PPM. ‘Normally, ttfautohint rounds the x height to the pixel grid, with a slight preference for rounding up. (…) Use this flag to increase the legibility of small sizes if necessary.’
Advice: leave the field empty at first to keep to the defaults, and only adjust if you are not happy with the x-height. Set to 0 if you want to switch off rounding up the x-height.
x-Height Snapping Exceptions: ‘list of comma-separated PPM values or value ranges at which no x-height snapping shall be applied’, e.g., ‘8, 10-13, 16’ disables x-height snapping for sizes 8, 10, 11, 12, 13, and 16. An empty string means no exceptions, and a mere dash (‘-’) disables snapping for all sizes.
Advice: leave the field empty at first to keep to the defaults, and only adjust if you are not happy with the x-height.
Adjust Subglyphs (formerly known as Pre-Hinting): If enabled, ‘makes a font’s original bytecode be applied to all glyphs before it is replaced with bytecode created by ttfautohint. This makes only sense if your font already has some hints in it that modify the shape even at EM size (normally 2048px); in particular, some CJK fonts need this because the bytecode is used to scale and shift subglyphs (hence the option’s long name). For most fonts, however, this is not the case.’
Advice: leave off. Can cause grave distortions. Only use if you know what you are doing and actually working on a CJK font.
Dehint: Disables all TT hinting, and therefore overrides all other options. Use only for testing.
Advice: just ignore this option. Better use the Autohint checkbox in the export dialog for this. It only makes sense to use this option if you have manual TT hints in the font and want to export without any hinting at all. In that case, check both Dehint in the custom parameter and Autohinting in the export dialog.
Detailed Info: if enabled, adds ‘ttfautohint version and command line information to the version string or strings (with name ID 5) in the font’s
nametable. This option is mutually exclusive’ with the No Autohint Info option (see below). ‘If neither is set, the string “ttfautohint (vNNN)” gets added to the
nametable’, NNN being the ttfautohint version.
Advice: ignore this option unless you have a post-production workflow that requires this setting.
Hint Composites: ‘By default, the components of a composite glyph get hinted separately. If this flag is set, the composite glyph itself gets hinted (and the hints of the components are ignored). Using this flag increases the bytecode size a lot, however, it might yield better hinting results – usually, it doesn’t.’
Advice: leave off. This was intended for very specific set-ups, and can cause grave distortions in most renderings, especially if not all components are at 100% scale.
Ignore Restrictions: ‘By default, fonts that have bit 1 set in the fsType field of the
OS/2table are rejected. If you have a permission of the font’s legal owner to modify the font, specify this command line option.’
Advice: ignore the checkbox. You will probably never need this in Glyphs.
No Autohint Info: if checked, prevents adding ‘ttfautohint version and command line information to the version string or strings (with name ID 5) in the font’s
Advice: turn on for shipping fonts.
Symbol Font: ‘Process a font that ttfautohint would refuse otherwise because it can’t find a single standard character for any of the supported scripts. For all scripts that lack proper standard characters, ttfautohint uses a default (hinting) value for the standard stem width instead of deriving it from a script’s set of standard characters (…). Use this option – usually in combination with the Fallback Script and/or Fallback Stem Width option – to hint symbol or dingbat fonts or math glyphs, for example.’
Advice: the doc says it all. Use this only for non-typeface fonts. And if that is the case, make sure Fallback Stem Width and Fallback Script are set as well.
ttfa table: Adds an OpenType table ‘called
TTFAto the output font that holds a dump of all parameters. In particular, it lists all ttfautohint control instructions (which are not shown in the name table info). This option is mainly for archival purposes so that all information used to create a font is stored in the font itself. Note that such a
TTFAtable gets ignored by all TrueType rendering engines. Forthcoming versions of the ttfautohint front-ends will be able to use this data so that a font can be processed another time with exactly the same parameters, thus providing a means for round-tripping fonts.’
Advice: ignore this option unless you have a post-production workflow that requires this setting.
Windows Compatibility: ‘This option makes ttfAutohint add two artificial blue zones, positioned at the
winDescentvalues (from the font’s
OS/2table). The idea is to help ttfautohint so that the hinted glyphs stay within this horizontal stripe since Windows clips everything falling outside.’ Use this option if clipping occurs in Microsoft Windows and you cannot adjust
winDescentinstead (which would usually be the better option). In combination with ‘-’ as value for xHeight Snapping Exceptions (see above), it should both ‘suppress any vertical enlargement’ and ‘prevent almost all clipping.’
Advice: always on, unless you have experimental
winDescentsettings. But I hope you don’t.
Horizontal Stem Width Mode: Stem widths and alignment zone positions are calculated in three possible ways:
- natural: No adjustments to stem widths, discrete zone positioning. No glyph shape distortion, little contrast (i.e., much anti-aliasing). Preserves the shape the most, but the text will be fuzzy. Best for high resolutions.
- quantized: Both stem widths and zone positions are slightly quantized to take discrete values. More glyph shape distortion, and increased contrast. Good compromise.
- strong: Stem widths and blue zones are snapped and positioned to integer pixel values as much as possible. High contrast (i.e., little anti-aliasing and very sharp pixels), but glyph shape distortion can be significant. The sharp, almost black-and-white rendering of the text gives good legibility on low-resolution displays.
These three algorithms are mapped onto three possible rendering targets: Grayscale (Microsoft Word and handheld systems such as Android devices), GDI ClearType (old versions of Windows like XP), and DW ClearType (since Windows 7).
Advice: Pick quantized for Grayscale and DW, and strong for GDI. If your client complains that the font appears too pixelated, go softer: strong → quantized → natural. If they complain that it is too blurry, go the opposite direction and make it sharper: natural → quantized → strong.
One note: the term ‘horizontal stem width’ may be confusing, because what is horizontal is not the stem, but the width. In other words, it is the horizontally measured width of the vertical stem.
There is one more setting that may have influence on the rendering of your TrueType font: ‘GASP’, short for ‘Grid-fitting and Scan-conversion Procedure’. In short, it is a font-wide custom parameter that will add a gasp table to your TTF.
Essentially, the font will be rendered differently at different sizes in order to increase legibility. It can be rendered with or without gridfitting (increased snapping to pixel edges), and symmetrically or asymmetrically (with more or less antialiasing). Or… actually not, because a renderer may ignore GASP altogether, ha ha ha. So do not waste too much time and effort on this setting, otherwise the joke is on you.
On the other hand, all you need to do for setting up GASP, is define two pixel sizes:
- No hinting & symmetric from 0 to the first size (default 8px): no gridfitting is applied, and text is rendered with antialiasing wherever possible.
- Hinting & asymmetric between first and second size (default 20px): gridfitting is applied and text is rendered as sharp as possible. In ClearType, the matter is handled asymmetrically, i.e., vertical gridfitting is applied, while horizontally, subpixel rendering is used.
- Hinting & symmetric above the second size: gridfitting is applied, and shapes are rendered with antialiasing.
Useful scripts and plug-ins
In the mekkablue scripts, you will find a couple of scripts that will make your hinting life easier.
- Hinting > Set ttfautohint Options: allows you to batch-set TTFAutohint options parameters for all instances that have the parameter already (will ignore instances without), including a smart way to batch-set individual fallback stem widths.
- Font Info > Clean Version String: among other things, will add the No Autohint Info setting in all TTFAutohint options parameters.
- Hinting > Remove TT Hints: deletes all manual TT hints so you can focus on autohinting.
- Test > Copy Word Test Text: will put all characters you can access in Microsoft Word in your clipboard, along with extra paragraphs for accessible OT features. You will need to apply the features yourself though.
- Test > Webfont Test HTML: creates and opens an HTML in the most recent export destination of your static fonts. Run this right after you exported the fonts.
ttfautohint was developed by Austrian musician and programmer Werner Lemberg. So when you search for him on the internets, do not be scared if you find more music than type.
- ttfautohint documentation, part of the Freetype project. Put this in your bookmarks.
- Werner’s talk about hinting Noto at TypeLabs 2017
- OT specification for the gasp table
SAMPLE FONT COURTESY OF RASMUS LUND MATHISEN.
Update 2022-09-14: corrected spelling of ‘ttfautohint’ (thx Werner), corrected a passage about the autohinting built into macOS (thx Ned).