This is a pretty rough compiler for the Kerning Input File, a text file
to kern fonts in TrueType AAT. It builds the state machine-based kerning
and positioning data in form of the kerx
and ankr
tables found
recently in AAT, and fuses that data into a font with OS X Font Tools.
If you’ve ever worked with a more recent version of Apple’s font tool suite, you’ve most likely noticed that among the input files used by the suite there’s no Kerning Input File, thus no apparent way of building AAT kerning data into a font.
It’s not entirely clear what happened to Kerning Input File. Just ‘Mach’ Wust, who seemed to be the first person to raise this issue publicly in a message to the CoreText mailing list, points out a passage in the suite’s documentation that mentions a Kerning Input File, but with no further description as well as no evident support in the tools themselves. (See also FontForge archives and notes to the Free Tengwar Font Project that document Just’s findings.) It was the legacy version of Apple’s tools that presumably did make use of the file, but they are no longer available to download and they wouldn’t run on a modern machine anyway. The documentation has also been redacted since.
Still, the part of font data Kerning Input File was supposed to compile into worked fine on all current Apple platforms and I’ve been building this data in hex at first. I’d keep an auxiliary text file as a notepad for the kerning definitions I was dealing with that would eventually become the input file read by the compiler — itself an ad hoc translator of the file into a hex code I’d otherwise write by hand.
In any event, because there’s no documentation on the original file format, as well as no examples of its syntax left in the wild, Kerning Input File as defined below is just a hack: a straightforward, if not simplistic, approximation of the format based on Morph Input File, a more widespread format still used by the suite.
You'll need a copy of the Font Tools available from the Fonts section at Apple Developer site. You'll be asked to sign into your Apple account before download, or to create one if you don't have one already.
Below you can find a description of the Kerning Input File. Having your kerning file ready, and the font file in place, run:
./kif.sh kerning.kif font.ttf
If your input file involves any anchor-based positioning, you'll need an
extra file with your anchor data passed through an -a
option to the
compiler:
./kif.sh -a anchors.kif kerning.kif font.ttf
Note: Helper files named post.xml
, kerx.xml
, and ankr.xml
for
anchors will be created next to your font file. If these conflict with
your workflow in any way, please see Troubleshooting below.
The following syntax is derived from the conventions found in Morph Input File and other input files used by Apple Font Tool Suite. If you've ever worked with MIF, the following will look familiar; if not, please see the relevant chapter in the suite's documentation first.
Kerning table in AAT is a sequence of subtables with different types of
data. Each subtable has a header with two required fields, Type
and
Orientation
, and one optional Cross-stream
field having a yes
/no
value that defaults to no
if the field is omitted:
Type Contextual/Attachment
Orientation H/V
Cross-stream yes/no
Both class lookup and the state table have the same form throughout all of the state machines in AAT, so their syntax follow the MIF literally. Modified are the entry table and the actions that follow, as to meet the requirements of the kerning table. The differences are described below.
In the contextual kerning subtable, entries have a Push?
flag, which
pushes the current glyph onto the kern stack, and a single action,
KernValues
, that names the list of kern values to apply on the stack:
GoTo Push? Advance? KernValues
1 StateName yes/no yes/no ListName/none
2 ...
Lists of values follow, each with a name on its own line, and the values indented on the line beneath. Each value is applied to the kern stack in order of popping the stack glyph by glyph until the list is consumed:
ListName
KernValue KernValue ...
For the cross-stream kerning subtables, a special value, Reset
, can be
used within the list of values. It makes the glyph to which it is
applied be reset to baseline from any accumulated cross-stream kern.
In the attachment positioning subtable, there's the usual Mark?
flag,
which marks the current glyph for later use, and one of three possible
types of actions: MatchPoints
, MatchAnchors
, and MatchCoords
:
GoTo Mark? Advance? MatchPoints
1 StateName yes/no yes/no PointSetName/none
2 ...
GoTo Mark? Advance? MatchAnchors
1 StateName yes/no yes/no AnchorSetName/none
2 ...
GoTo Mark? Advance? MatchCoords
1 StateName yes/no yes/no CoordSetName/none
2 ...
Each action type declares if the values are to be read as control point numbers, anchor numbers, or pairs of coordinates, and each refers to a set of both marked and current glyph values that define the match point. These are defined last, and take a form respective to the action type:
PointSetName
Marked PointNumber
Current PointNumber
AnchorSetName
Marked AnchorNumber
Current AnchorNumber
CoordSetName
Marked XCoord YCoord
Current XCoord YCoord
For each type, the points the values resolve to within a given glyph space are used to align the current glyph to the marked one so that the points in both glyphs match.
This concludes a subtable and the main part of the KIF syntax. For the anchor table that's used with anchor-based positioning, a separate input file is needed. It's a simple list of anchors in the following format.
Right at the top of the file there are the usual glyph classes as found in other input files of AAT. These could, in fact, be reused verbatim from the subtables in the kerning file the anchors are to be used with.
Below lies the AnchorList
header, separating the classes from the list
of anchors. Now anchors are just pairs of coordinates grouped under the
names of the respective glyph classes. Referred class name goes up front
on its own line, and the coordinates on the indented lines beneath:
AnchorList
ClassName
XCoord YCoord
XCoord YCoord
...
ClassName
XCoord YCoord
...
That's all that goes into the anchor input file. Please see the accompanying example directory for some examples and more commentary.
Both your input files are translated into data files full of hex code
for your kerx
and ankr
tables that are then fused into the font. If
you run the compiler with a -d
flag, these intermediate data files
will include comments and references to your input file, what can be of
much help in case something goes wrong in the process. Moreover, to
produce the files without actually fusing them in, use an -n
option:
./kif.sh -d -n -a anchors.kif kerning.kif font.ttf
Data files named kerx.xml
and ankr.xml
are created next to your font
file. You can look into them, or fuse into the font yourself with a
variation on the following command:
ftxdumperfuser --generic --table kerx --datafile kerx.xml font.ttf
Every time you run the compiler, the post
table of your font is being
dumped into a post.xml
file for a quicker glyph name lookup. If you
don't want it to happen repeatedly, you can either reuse the post.xml
file that has been dumped already, or make one manually beforehand:
ftxdumperfuser --table post --output post.xml font.ttf
In either case, point it to the compiler through a -p
option:
./kif.sh -p post.xml -a anchors.kif kerning.kif font.ttf
Note that providing the post
dump explicitly is sufficient to build
the data files and the font itself may be skipped. This in case you
either can't or don't want to use the Font Tools, or would rather like
to run the compiler simply as an file.kif
to data.xml
translator:
./kif.sh -n -p post.xml -a anchors.kif kerning.kif
In such case, both data files will be created in the current directory.
For now, only the two, both state machine-based subtables for contextual
kerning and attachment are available to use. Moreover, the relatively
recent attachment positioning can be used within the kerx
table only.
The kerx
extended kerning table is not fully documented, so consider
the code produced as being in part reverse-engineered with all the usual
caveats. In case any issues should arise, an -l
option to the compiler
will produce the legacy kern
table that's still supported in CoreText
on both OS X and iOS.
Specifying kerning variations, part of the TrueType Variations technology found originally in AAT, is also currently not available.
This work is copyrighted by Grzegorz Rolek, 2013, and is subject to the BSD 3-Clause License. Please see LICENSE for details.