Low-level elements
Though Xgridfit tries to provide as much functionality as possible in its high-level programming constructs, there may well be times when you feel you need to write low-level, "raw" instructions, either because Xgridfit does not meet some particular need or because a job can be done most efficiently with low-level instructions. Xgridfit provides three elements to help you write low-level code.
<command>
The <command> element will insert any TrueType instruction into your Xgridfit program. If the command reads values from the stack or writes to it, it is up to you to manage the stack yourself. Here is a simple example:
<command name="ALIGNRP"/>
A number of instructions take one or more bits as modifiers. For example, the MIAP instruction, which positions a point at a grid coordinate read from the control-value table, takes a single modifier bit that indicates whether the control-value should be rounded before the point is positioned. The modifier can be noted in more than one way, even when entered in FontForge:
MIAP[1] MIAP[rnd]
There are two ways to insert modifiers in Xgridfit: one is compact, easy and possibly non-portable, and the other is verbose but portable. The compact method is to include a modifier attribute containing a string which is to be copied verbatim into Xgridfit's output code:
<command name="MIAP" modifier="1"/> <command name="MIRP" modifier="01100"/>
The verbose method is to include one or more <modifier> elements as children of <command>. Each element defines a bit:
<command name="MIAP"> <modifier type="round" value="yes"/> </command> <command name="MIRP"> <modifier type="set-rp0" value="no"/> <modifier type="round" value="yes"/> <modifier type="minimum-distance" value="yes"/> <modifier type="color" value="gray"/> </command>
At present there is no advantage, aside from legibility (and who cares about that?), to using <modifier>. But if Xgridfit at some future time acquires the ability to produce input for some font production program other than FontForge, the verbose method is guaranteed to work while the compact method is not.
It is not necessary to provide a <modifier> for every bit that can accompany an instruction: all modifier types have defaults. Here are the modifier types, with all possible values, and with defaults in bold:
- set-rp0: yes, no.
- round: yes, no.
- minimum-distance: yes, no.
- color: gray, black, white.
- grid-fitted: yes, no.
- to-line: parallel, orthogonal.
- axis: x, y.
- ref-ptr: 1, 0.
If you are planning to write low-level code, you presumably know already which instructions have modifier bits and what those bits do. If you do not, consult the TrueType Reference Manual.
<push>
Many TrueType instructions operate upon values they pop from the stack; thus you must have have a way to push values onto the stack. TrueType provides a variety of PUSH instructions, depending on how the values are stored in the program code (as bytes or words) and how many values need to be pushed. Xgridfit reduces this variety to a single element: <push>, which takes a list of values. These can be number literals, constants, control-value indexes, simple expressions, indeed any values that can be resolved to single numbers at compile time. These are valid Xgridfit <push> instructions:
<push>2 5 89 67</push> <push> left right lc-vertical-stem -1 </push> <push> 0.58p 2.0 to-grid </push> <push>1 (top + 3) 512</push>
Notice that all expressions containing whitespace must be enclosed in parentheses. Xgridfit always pushes all the numbers contained in the <push> element with one instruction. It uses a PUSHB instruction where possible; otherwise a PUSHW instruction.
Trying to push an identifier or expression that cannot be resolved to a single number at compile time generates an error message. So does an empty <push></push> element.
<to-stack>
<to-stack> is similar to <push> in that its purpose is to move a value onto the top of the stack. But <to-stack> can handle any value recognized by Xgridfit, whether it can be resolved to a number at compile-time or at run-time. It generates whatever instructions are necessary to move the value to the top of the stack. Thus it can handle variables, graphics variables, control values (not just their indexes), function parameters, and complex expressions.
<to-stack> has one significant limitation: a single <to-stack> element can handle only a single value. It cannot take a list of values as <push> can.
Here is an example of the use of <to-stack> in a fragment of code from a function, in which the point line-2-a and the control-value cvt have been passed in as parameters:
<to-stack>line-2-a</to-stack> <to-stack>cvt</to-stack> <command name="MIRP"> <modifier type="color" value="black"/> </command>
This code fragment also shows, incidentally, how a <command> element can be abbreviated by accepting defaults. It is functionally the same as this:
<command name="MIRP"> <modifier type="set-rp0" value="yes"/> <modifier type="minimum-distance" value="yes"/> <modifier type="round" value="yes"/> <modifier type="color" value="black"/> </command>