Contact Us


Initiative B@bel

WSI Guidelines


















Type Design


Design Tools



Font Downloads










Font FAQ



NRSI: Computers & Writing Systems


You are here: Rendering > Resources
Short URL: http://scripts.sil.org/TypeTuner_designers

SIL TypeTuner for Font Designers

Alan Ward, 2009-04-28


Before digging into this documentation, it is advisable to understand the user documentation for SIL TypeTuner. A general understanding of  TrueType font internals is assumed. If you want to manipulate the OpenType features in a font, a working knowledge of the  OpenType feature structures and of how the Perl Font-TTF library handles those structures is also necessary.

Developer resources

The Font::TTF::Scripts module in the Perl version of FontUtils includes a doc\TypeTuner_dev folder that contains the following:

  • feat_all.dtd
  • feat_set.dtd
  • feat_all.sample.xml

There is one DTD (feat_all.dtd) for the file which describes all the features in a font and provides the details of how the font should be changed for those features. This XML file is called the Features file. There is another DTD (feat_set.dtd) for the file that a user edits to specify their feature settings. This XML file is called the Settings file.

feat_all.sample.xml is a test file which was created during development that exercises all the capabilities of TypeTuner (especially nested cmd_blocks).

Two other scripts that are part of FontUtils may be especially useful. The ttfprintot script (in the Examples folder) will display the OpenType script/language/feature/lookup structure in a font. The ttflang2tuner script can create a draft Features file.

The Features file

The root element for the Features file is all_features. Directly under it are numerous feature elements. These elements make up the first section of the file. This section is followed by four optional sections each of which is contained within an XML element. The optional sections are: interactions, aliases, command blocks, and old names


<feature name="Barred-bowl forms" value="False" tag="BarBwl">
    <value name="False" tag="f">
        <cmd name="null" args="null"/>
    <value name="True" tag="t">
        <cmd name="gr_feat" args="1031 1"/>
        <cmd name="encode" args="0180 uni0180.BarBowl"/>
        <!-- lines removed -->

Each feature element specifies the name of a feature and enumerates its possible settings in value elements. The default setting is specified in the feature's value attribute, and tags for the feature and settings are indicated with tag attributes. The commands to apply to the font for each setting are given by cmd (and cmds) elements.


Each feature must have a unique tag and each setting must have a tag that is unique within a feature. Tags cannot contain spaces or hyphens. They should be short but somewhat readable. They will be added to the font name for non-default feature settings, so keep in mind how long this suffix could get if you have many features. Globally, if a feature or setting name is reused, the tag must be the same. For example, "True" is a common setting. If the tag for "True" is "T" in one place, the tag must be same everywhere that "True" is used.

The tags for features and settings are used to specify a string for a given feature setting by concatenating the tags together with a hyphen. For example, "Barred-bowl forms" set to "True" might be represented as "BarBwl-T". Tests in the Interaction section are specified using this notation. The tags for feature settings are appended to the font version string and appended to the font name (if the -n switch is not specified). When the tag is used in these areas, the hyphen is removed and any "True" tag is removed. For example, if the tag is "BarBwl-T", "BarBwl" will be added to the font name and version.

The length of the font name suffix can be limited using the -m switch. The TrueType specification states that the maximum length for the font family name is 31 characters. The default for the -m switch will be set based on the length of the original font family name so that the 31 character limit is respected. If the -m switch specifies a value that will cause this limit to be exceeded, a warning will be given.


    <test select="BarBwl-T Lit-T">
        <cmd name="encode" args="01E5 uni01E5.BarBowl.SngBowl"/>
        <!-- lines removed -->

The purpose of each test element is to specify what commands to apply if two or more features are set. Usually this is only relevant if multiple feature settings affect the same character(s). The select attribute on each test element specifies the feature settings to test as explained in the Tags section above. If the user has specified all the settings listed in the select attribute, the cmd (and cmds) subelements will be applied to the font.

Feature and Interactions precedence

The settings that a user specifies are matched against the appropriate feature value elements first, then the settings are tested against the interactions test elements. Within the interactions section, tests with the least terms are tested first. If multiple tests have the same number of terms, they are tested in alphabetical order (treating the test select attributes as strings).

This processing order means that mutiple commands may be applied from several sections of the Feature file. The author must construct the file with this in mind.


<cmd name="encode" args="1EA5 uni1EA5.SngStory"/>
<cmd name="line_gap" args="2000 750"/>
<cmd name="line_metrics" args="1900 750 100 2000 750 2000 749 20"/>
<cmd name="line_metrics_scaled" args="null"/>
<cmd name="gr_feat" args="1032 1"/>
<cmd name="lookup_add" args="GSUB {ccmp_latin} {viet_decomp}"/>
<cmd name="lookup_del" args="GSUB {ccmp_latin} {viet_decomp}"/>
<cmd name="feat_add" args="GSUB latn {IPA} {ccmp_vietnamese} 0"/>
<cmd name="feat_del" args="GSUB latn {IPA} {ccmp_latin}"/>
<cmd name="null" args="2324 810"/>

The cmd elements specify actions to be applied to a font. The name attribute gives the command name and the args attribute specifies arguments for the command. Arguments are space-delimited so if an argument needs to contain a space, an alias must be used. If multiple commands that do the same thing are applied, the last one "wins". For example, if two encode commands affect the same codepoint, the glyph specified in the second command is encoded. A detailed knowledge of the font's internal data is needed to specify the commands.

  • encode: Encodes a glyph. The arguments are the Unicode codepoint and the PostScript name for a glyph.
  • line_gap: Modifies the line spacing in a font. The arguments are the new ascent and descent. Descent should normally be positive.
  • line_metrics: Modifies the line spacing in a font by providing all eight line metric values. The arguments are: ( OS/2) TypoAscent, TypoDescent, TypoLineGap, WinAscent, WinDescent, ( hhea) Ascent, Descent, LineGap. All the Descent values should normally be positive.
  • line_metrics_scaled: Modifies the line spacing in a font to match the line spacing in a source font. The argument in the Features file must be null. The actual arguments are obtained from the <Imported_line_metrics> element in the Settings file (see the feat_set.dtd). The attributes of this element specify the following data from the source font: font name, em square, and line metrics (in the same order as the line_metrics command). The <Imported_line_metrics> element is usually created using TypeTuner's setmetrics command (see Importing line metrics from a legacy font). When the line metrics are applied to the tuned font, they are scaled based on the ratio of the em square in the font to the em square stored in the Settings file.
  • gr_feat: Changes the default setting for a Graphite feature. The arguments are the feature id and the setting id for the new default.
  • lookup_add: Adds an  OpenType lookup to a given feature. The arguments are the OpenType table (GSUB or GPOS), the feature id, and the lookup id as specified in the Perl Font-TTF library. In the above examples, aliases are used to increase readability. The lookup will be added in sorted order.
  • lookup_del: Deletes an OpenType lookup from a given feature. The arguments are the same as lookup_add.
  • feat_add: Adds an OpenType feature to a given script and language. The arguments are the OpenType table (GSUB or GPOS), the script, the language, and the feature id as specified in the Perl Font-TTF library. A final argument indicates the position in the list of features where the added feature should be inserted.
  • feat_del: Deletes an OpenType feature from a given script and language. The arguments are the same as for feat_add but without the final argument.
  • null: Does nothing. This command is used for the default setting. The arguments are not interpreted and can be anything.


<cmd name="lookup_add" args="GSUB {ccmp_latin} {viet_decomp}"/>

    <alias name="IPA" value="IPA "/>
    <alias name="ccmp_latin" value="ccmp"/>
    <alias name="ccmp_romanian" value="ccmp _0"/>
    <alias name="viet_decomp" value="4"/>

Aliases can be used as arguments in cmd elements. They are provided for readability and to support arguments that contain spaces. The alias should be enclosed in curly brackets (eg {IPA}) where it is used.

Command blocks

<test select="LA-t BB-t">
    <cmds name="LitAltsBB"/>
    <cmd name="encode" args="01E5 uni01E5.BarBowl.SngBowl"/>

    <cmd_block name="LitAltsBB">
        <cmd name="encode" args="0061 a.SngStory"/>
        <cmds name="bar"/>
        <cmd name="encode" args="0067 g.SngBowl"/>
    <cmd_block name="bar">
        <cmd name="xyz" args="1 2"/>
        <cmd name="fgh" args="4 5"/>

The purpose of cmd_blocks is to eliminate redundant lists of cmd elements and replace such a list with a named reference to the list.

A cmds element can be used any place that a cmd element could be. The name attribute for the cmds element should refer to a cmd_block name in the cmd_blocks section. The cmd_block element contains cmd elements which will be substituted in the place where the cmds element appears. The cmd_block can also contain cmds elements which will be processed in the same way. Caution should be used to avoid creating loops.

Old Names

The old_names section provides a mechanism for mapping old feature or value names to current tags. Typically the name change would occur because of a new font release.

    <old_feature name="J stroke hook alternate" tag="JStrk"/>
    <old_value feature="Small v-hook alternate" name="Straight" tag="StrtLftLowHk"/>

The old_names element can contain old_feature and old_value elements. Both of these elements specify a name used in a previous version of the font and a tag used in the current version.

Additionally, the old_value element specifies the previous name of the feature (which may not have changed) that contains the value. The feature needs to be specified because two features can enumerate the same value, but in a new font version, only one of those values might change.

Notes on developing a Features file

The Features file should be developed and validated with the feat_all.dtd file. To test the Features file, use the TypeTuner createset command with the -t switch and the Features file to generate a Settings file with all settings at non-default values. Next apply the Settings file to a font using the applyset_xml command with the -d switch. If there are multi-valued features, the Settings file should be edited and reapplied to the font to test all settings. All these steps are necessary to completely test the Features file for internal consistency.

When the Features file is done, create a Tuner-ready font by using the add command. This command will place the Features file into the font's Silt table in a compressed form. The Tuner-ready font should be tested by following the example on the SIL TypeTuner page to be sure it will work the way most users expect. Note that a derivative font that a user creates will have the Settings file (instead of the Features file) embedded in the Silt table in compressed form. A tuned font cannot be re-tuned.



TypeTuner is part of FontUtils.

Please note that the above page is a work in progress. Sometimes this documentation will be out of sync with the latest FontUtils release. The latest source code can be obtained from Subversion.

© 2003-2017 SIL International, all rights reserved, unless otherwise noted elsewhere on this page.
Provided by SIL's Non-Roman Script Initiative. Contact us here.