Xgridfit
Author: Peter S. Baker

Home Page Project Page Download CVS repository

# Converting Existing Instructions

The method described here is deprecated, though it does still work. For a simpler method, click this link.

It is possible to use Xgridfit to add instructions to fonts containing instructions added "by hand" or by other programs. Using a simple utility included with Xgridfit, you can extract from a font all existing control values, functions, pre-program, glyph programs, and such maxp entries as relate to instructions, and make these the basis of a new Xgridfit file. In this new file, existing functions are sequestered in a <legacy-functions> element, and any functions, control values and variables that you add to the file are automatically indexed so as not to conflict with existing ones.

To create the new Xgridfit file, you must first install TTX, a utility in the FontTools package: this program converts a TrueType font to XML. Get the latest version here and follow the installation instructions (it requires the Python programming language). You also need version 1.0 or later of Xgridfit. Make a directory and copy into it the font you are working with (this must be the TrueType font file, not a FontForge SFD file). Run TTX on the font file:

        $ ttx DejaVuSerif.ttf

This creates a TTX file named `DejaVuSerif.ttx`. Now run `ttx2xgf`, thus:

        $ ttx2xgf DejaVuSerif.ttx
          or
        $ ttx2xgf DejaVuSerif

The output of either command is an Xgridfit file named `DejaVuSerif.xgf` (if you want a differently named file, just supply the name as a second argument). Before you use the new file, you should check the <legacy-functions> element for correctness, as explained in the next few paragraphs. This check ensures that Xgridfit will correctly number its predefined functions and functions you define. (Note, however, that if the font you are working with was hinted by the FontForge auto-instructor, this check is unnecessary. You can be sure that your new Xgridfit program is correct.)

Open the new Xgridfit file with a text editor and locate the <legacy-functions> element. Take note of the attribute `max-function-defs`. This number, taken from the font's maxp table, must be one greater than the highest function number (for in TrueType fonts functions are numbered, not named).

Very likely the function numbers are assigned in one of two ways. Some fonts push all the function numbers onto the stack before defining any functions. In that case, the first lines of the <legacy-functions> element will look something like this:

        <push>6 5 4 3 2 1 0</push>
        <command name="FDEF"/>

Alternatively, the function number may be pushed just before each function is defined, thus:

        <push>0</push>
        <command name="FDEF"/>

In the former case the correct value for `max-function-defs` is one greater than the highest number in the list (here 6, so max-function-defs should be 7). In the latter case you must scan the PUSH instructions that precede each FDEF instruction to find the highest number. Please note, in case this seems esoteric, that the `max-function-defs` attribute will already be correct if the font you are converting was correctly made.

Notice that the new Xgridfit file can be run against a FontForge (SFD) file even though it was extracted from a font file. You may either open FontForge and run the script you have generated from within the GUI, or add <infile> and <outfile> elements so that you can run the script from the command line, for example:

          <infile>DejaVuSerif.sfd</infile>
          <outfile>DejaVuSerif.ttf</outfile>

Now you are ready to test the new file. It should produce a font that is functionally identical to the one you started with. You may delete the TTX file if you have no further use for it.

## Notes and Cautions

`ttx2xgf` breaks up very long PUSH instructions. This can prevent problems later on, when running a generated script in FontForge. However, it may cause problems in a very narrow set of circumstances. Specifically, it can change the offset needed by a nearby JMPR, JROF or JROT instruction. This is unlikely; but if the font you are converting uses JMPR, JROF or JROT, you should make sure that one of these instructions is not trying to jump over a long PUSH instruction that has been broken up.

At the end of the list of <control-value> elements, `ttx2xgf` inserts a comment warning that <control-value> elements should not be added to or deleted from the preceding list, and their order should not be changed. Any change of this kind will change the indexing of control values, with serious consequences. New control values may be added to the list only after the comment.

The `name` attributes of existing <control-value> elements can and often should be edited, so that legacy control values can more easily be reused. For example, in DejaVu Regular, it takes only a little research to discover that a standard vertical stem for a lower-case letter is regulated with control value 39, for which the generated `name` is `cv-39`. It makes sense to change this `name` to "lc-vertical-stem" or the like, and use it in writing instructions for other lower-case letters with vertical stems. However, it would be unwise to change the `value` of this <control-value>, and catastrophic to move the element from its original location in the list.

Xgridfit has an older method for handling legacy functions--namely, adding a `num` attribute to some functions to force the use of a particular number identifier. This method is not compatible with the use of <legacy-functions>, and you should not attempt to use both in the same file.

`ttx2xgf` also generates several useful constants:

          <constant name="left-sidebearing" value="last + 1"/>
          <constant name="right-sidebearing" value="last + 2"/>
          <constant name="vertical" value="0"/>
          <constant name="horizontal" value="1"/>
          <constant name="true" value="1"/>
          <constant name="false" value="0"/>

If you include a constant "last" with the number of the last outline point at the beginning of each glyph program, then `left-sidebearing` and `right-sidebearing` will always point correctly to the left and right sidebearing points, and can be accessed from any glyph program. The values `vertical` and `horizontal` are used by the TrueType vector setting instructions and may be useful in various contexts. The `true` and `false` values can be used to set variables to boolean values or evaluate boolean expressions, and they are boolean expressions themselves.

## Non-Linux systems

The `ttx2xgf` utility is a Bash script for Linux, which invokes two programs: one an XSLT script and the other a Sed script. It should also work perfectly well under Mac OS X. If you are using a system other than Linux or OS X, you may reproduce the functionality of `ttx2xgf` by running these scripts yourself. First use your favorite XSLT processor to run the script `convert-ttx.xsl` against the TTX file you generated with the cross-platform TTX utility. Next use Sed (also available for various systems) to run the script convert-asm.sed against the file generated in the first step. The result of these two simple steps should be a valid Xgridfit file.