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.