Xgridfit
Author: Peter S. Baker

Home Page Project Page Download CVS repository

<move> <diagonal-stem> <interpolate> <interpolate-untouched-points> <untouch> <align> <align-midway> <shift> <shift-absolute> <move-point-to-intersection> <set-coordinate> <flip-off> <flip-on> <toggle-points> <mirp> <mdrp> <miap> <mdap>

# Instructions that Move Points

The most important Xgridfit instruction is <move>. This may move a point to an absolute position on the raster grid, to the nearest gridline (or rounded position), or to a position relative to another point. <move> does the work of the TrueType MIRP, MDRP, MSIRP, MIAP, MDAP and SCFS instructions. (Xgridfit provides equivalents of most of these primitive instructions, but their use is not recommended except in special circumstances.)

Other commonly used instructions are <shift>, <align> and <interpolate>. These are generally subordinate to <move>: that is, after <move> has moved a point, these instructions are used to shift other points along with it (<shift>), align other points with it (<align>), or reposition some points so that they are properly located between it and another moved point (<interpolate>). Another instruction, <delta>, which moves a point an absolute distance at a specific size, is discussed in its own section.

Some of the following instructions should be avoided in favor of higher level instructions but are here in case they're needed, or in case the programmer wants to produce more efficient code. Such instructions have cryptic names (e.g. <mirp>) that echo the mnemonics for TrueType instructions. Those that are suitable for frequent use have clearer, fuller names (e.g. <shift>).

### <move>

Moves a point and, optionally, aligns other points with it or moves other points in relation to it.

The only required item is a point to move. Xgridfit moves this point differently depending on the presence or absence of a reference point (explicit or, in the case of a <move> nested within a <move>, implicit) and the "distance" or "pixel-distance" attribute:

no reference point or distance attribute
  The point is moved to a position on the grid determined by the current position of the point and the round state: for example, if the round state is "to-grid," the point is moved to the nearest grid line. If rounding is off, the point is not moved, but "touched" as if it had been moved. In this example, the point "bottom" is moved to the nearest position halfway between two grid lines:

      <move round="to-half-grid">
        <point num="bottom"/>
      </move>

reference point but no distance attribute
  The point is moved so that its original distance from the reference point is maintained. The distance is rounded in accordance with the current round state. Here the original distance between "bottom" and "top" is rounded (presumably "to-grid"), and "top" is moved until it is that distance from "bottom":

      <move>
        <reference>
          <point num="bottom"/>
        </reference>
        <point num="top"/>
      </move>

reference point and distance attribute
  "Distance" is a value from a <control-value> element; the point is positioned this distance from the reference point. The distance is rounded in accordance with the current round state. Here the <control-value> "lc-height" is rounded and "top" is moved until it is that distance from "bottom":

      <move distance="lc-height">
        <reference>
          <point num="bottom"/>
        </reference>
        <point num="top"/>
      </move>

distance attribute but no reference point
  "Distance" is a value from a <control-value> element; the point is positioned this distance from the grid origin. The distance is rounded in accordance with the current round state. Here the <control-value> "lc-height" is rounded and "top" is moved until it is that distance from the grid origin. If the freedom and projection vectors are set to the `y` axis, the distance is measured from the baseline:

      <move distance="lc-height">
        <point num="top"/>
      </move>

reference point and pixel-distance attribute
  "Pixel-distance" is a distance in pixels (e.g. "2p" or "2.0" or "round(control-value(lc-height) * 0.8)"). The point is positioned this distance from the reference point:

      <move pixel-distance="2p">
        <reference>
          <point num="left"/>
        </reference>
        <point num="right"/>
      </move>

pixel-distance attribute but no reference point
  The point is positioned the specified distance from the grid origin:

      <move pixel-distance="2p">
        <point num="right"/>
      </move>

A top-level <move>--one that is not a child of another <move> element--always leaves the RP0 reference pointer set to the point just moved. When another <move> follows, with a reference point that matches the point just moved, Xgridfit optimizes the output, "chaining" the instructions generated by <move>. Here is a series of chained <move> elements:

        <move distance="std-stem-left-side" min-distance="no">
          <reference>
            <point num="left-sidebearing"/>
          </reference>
          <point num="stem-left"/>
        </move>
        <move distance="lc-vert-stem">
          <reference>
            <point num="stem-left"/>
          </reference>
          <point num="stem-right-a"/>
        </move>
        <move min-distance="no">
          <reference>
            <point num="stem-right-a"/>
          </reference>
          <point num="stem-right-b"/>
        </move>

A number of subordinate moves may be packaged inside a <move> element. This is done by including <interpolate>, <align>, <shift>, <delta> and other <move> instructions after the <point> element. The parent <move> element supplies the reference point or points for those child elements that take reference points (<delta> does not); in such child elements the <reference> element should be omitted, the reference point(s) being implicit. Here are further notes on the behavior of nested elements:

- The points and ranges in an <align> element are aligned with the point moved by the <move> instruction.
- You may include <interpolate> instructions if the <move> instruction contains either an explicit or an implicit reference point. The points and ranges in the <interpolate> instructions are interpolated between the reference point and the moved point.
- The points, ranges and contours in a <shift> element are shifted relative to the point moved by the <move> instruction.
- The point in a <move> element is moved relative to the point moved by the parent <move> instruction. Unlike a top-level <move>, a nested <move> does not leave RP0 set to its <point>; rather, RP0 always continues to point to the <point> in the parent <move>.
- You may include <delta> elements both before and after nested <align>, <interpolate>, <shift> and <move> elements. Deltas positioned before those elements are executed immediately after the <point> belonging to the parent <move> is moved, but before other nested elements are executed. Normally these deltas are used to make fine adjustments to the position of the point just moved; if you omit the <point> element in a <delta-set> here, the <point> belonging to the parent <move> is assumed. The <delta> elements that come after other nested elements are executed after all those elements have been executed: use these to make fine adjustments in the positions of the points moved by those other instructions.

You should use this nesting or packaging feature to build programming structures around the visible structures of the glyph. The payoffs for doing so are more compact and legible program code and more compact and efficient output. As an example, here are the horizontal instructions for a letter n:

        <move distance="fhijklmnt-left-side">
          <reference>
    	<point num="left-sidebearing"/>
          </reference>
          <point num="left-left"/>
          <move distance="top-serif-x-width">
    	<point num="top-serif-end"/>
          </move>
          <move distance="lc-serif-width">
    	<point num="left-serif-left-end"/>
          </move>
          <move distance="lc-vert-stroke">
    	<point num="left-right-a"/>
    	<align>
    	  <point num="left-right-b"/>
    	</align>
    	<move distance="lc-serif-width">
    	  <point num="left-serif-right-end"/>
    	</move>
          </move>
        </move>

        <move distance="hnu-width">
          <reference>
    	<point num="left-left"/>
          </reference>
          <point num="right-right"/>
          <delta>
    	<delta-set size="4" distance="-8"/>
          </delta>
          <move distance="lc-serif-width">
    	<point num="right-serif-right-end"/>
          </move>
          <move distance="lc-vert-stroke">
    	<point num="right-left"/>
    	<move distance="lc-serif-width">
    	  <point num="right-serif-left-end"/>
    	</move>
          </move>
        </move>

The first <move> block relates to the left "leg" of the n. First the point `left-left` is positioned relative to the `left-sidebearing` point; then the points that define the left ends of the serifs are positioned relative to `left-left`. Then `left-right-a` is positioned relative to `left-left`, `left-right-b` is aligned with `left-right-a`, and the right end of the left serif is positioned relative to `left-right-a`. The second <move> block works in a similar way, each element nested inside a <move> taking that element's <point> as a reference point. Note that the <delta> in this element moves the point `right-right`.

The figure above illustrates this code graphically, the thick lines showing the relationship among the reference points and moved points of the top-level <move> elements, and the thin lines showing the subordinate moves.

Remember that <move> elements are not "chained" inside other <move> elements as top-level <move> elements are. Rather, after a nested <move> RP0 always points to the <point> moved by the parent <move>. One might say that chaining inside the <move> is vertical, from parent to child, while otherwise is it horizontal, from sibling to sibling.

Elements nested inside a <move> must come in the following order:

- <delta>
- <align>, <interpolate>, <shift> (in any order),
- <move>
- <delta>

You may include more than one of each of these nested elements. Note that the order of <align>, <interpolate> and <shift> is not significant: Xgridfit sets the order in which these elements are executed. Normally this should not be a problem, as it would be very odd if the content of these elements were to overlap.

The <compile-if> element is not permitted in a <move>, but nested elements may be compiled conditionally with the `compile-if` attribute. For example, one set of deltas can be compiled if a font is bold and another if it is not bold (a "bold" constant, either true (1) or false (0) being defined in the top level of your program):

           <move>
             <point num="p"/>
             <delta compile-if="bold"/>
               <delta-set size="5" distance="2"/>
             </delta>
             <delta compile-if="not(bold)"/>
               <delta-set size="3" distance="-1"/>
             </delta>
           </delta>
    ˙

Bypassing the Control Value Table by using the pixel-distance attribute is usually unnecessary. Yet this attribute may occasionally be useful. For example, here is a function that guarantees at least one pixel of space between a character and the diacritic above it:

        <function id="ensure-diacritic-gap">
          <param name="char-top"/>
          <param name="diacritic-bottom"/>
          <param name="diacritic-contour"/>
          <variable id="d"/>
          <with-vectors axis="y">
            <measure-distance result-to="d">
              <point num="char-top"/>
              <point num="diacritic-bottom"/>
            </measure-distance>
            <if test="d &lt; 1p">
              <move pixel-distance="1p" round="no">
                <reference>
                  <point num="char-top">
                </reference>
                <point num="diacritic-bottom"/>
                <shift>
                  <contour num="diacritic-contour"/>
                </shift>
              </move>
            </if>
          </with-vectors>
        </function>

#### Attributes

distance
  A value from a <control-value> element. If a `distance` is specified, the target point is positioned that distance either from the reference point or from the grid origin. If a `distance` is not specified, the distance from the original outline is used. In either case, the `distance` is measured along the projection vector.
pixel-distance
  A distance in pixels. If a `pixel-distance` is specified, the target point is positioned that distance either from the reference point or from the grid origin. The `distance` and `pixel-distance` attributes are not compatible. If a `distance` attribute is present, the `pixel-distance` attribute is not consulted.
round
  Whether and how to round the `distance` or `pixel-distance`. The default value is `yes`, which means to round it according to the current setting (to the grid, if you haven't changed it). If you specify `no`, no rounding will be done. To use one of the standard round states, use `to-grid, to-half-grid, to-double-grid, down-to-grid` or `up-to-grid`. To use a custom round state, use its name. Finally, any number (constant, variable) is passed to SROUND for the TrueType engine to interpret. Setting the round state with this attribute has no effect except in this instruction: the round state returns to its former value after the instruction is executed. If several <move> instructions use the same round state, it is more efficient to enclose them in a <with-round-state> element than to include a `round` attribute with each one. That is also true if the `round` value is to be `no`: in that case use `<with-round-state round="no">` and omit the `round` attribute for the <move> instructions.
cut-in
  Whether to use the Control Value cut-in; or a cut-in value to use. Legal values are `yes`, `no` or any number; the default value is `yes`. If the value of this attribute is `no`, the value of the `round` attribute must also be `no`. (This is a peculiarity of the TrueType instruction set and has nothing to do with Xgridfit.) This attribute has an effect only when the `distance` attribute is present.
min-distance
  Whether to maintain a minimum distance between the reference point and the target point; or the minimum distance to use: legal values are `yes` (the default), `no`, or any number. This attribute has an effect only when there is a reference point.
color
  Distance type: `black`, `white` or `gray` (the default). This applies only when there is a reference point.
compile-if
  The <move> instruction and all its contents are compiled only if the expression in the `compile-if` attribute evaluates as true (non-zero). The instruction is also compiled if this attribute is omitted.

### <diagonal-stem>

Given two lines (making up a diagonal stem), makes the second line parallel to the first, subject to the operation of the Control Value cut-in. If one <align> element is present, the points it contains are aligned with the second line; if there are two, the first set of points is aligned with the first line and the second set with the second line. You may, and often should, set a new minimum distance value with the `min-amount` attribute. At the end of this instruction the minimum distance will be reset to its former value.

Usually it doesn't make a lot of sense to round the distance when calling this instruction; and yet the default value of `round` is `yes` for compatibility with other, similar instructions. You'll probably want to set the `round` attribute to `no`; but if you have several <diagonal-stem> instructions together, enclose them in a `<with-round-state round="no">` element to turn off rounding beforehand and on again afterwards. In this case, do not include the `round` attribute with the <diagonal-stem> elements.

By default this instruction does not set the Freedom Vector, since the best setting of that vector varies with circumstances. If you want the Freedom Vector to be the same as the Projection Vector, set `freedom-vector="yes"`.

This instruction is not suitable for use inside a function (though you may do so if the <line> elements contain points rather than `ref` attributes). Also, I'm not sure whether it will work if the various points are in different zones. It may, but I don't guarantee it.

Example:

      <diagonal-stem min-distance="yes" distance="cap-thin-diag" round="no">
        <line ref="left-left-line"/>
        <line ref="left-right-line"/>
        <align>
          <point num="left-right-b"/>
          <point num="left-right-c"/>
        </align>
      </diagonal-stem>

#### Attributes

distance
  A value from a <control-value> element: this controls the width of the diagonal stem.
round
  Whether and how to round the distance the point is to be moved. The default value is `yes`, which means to round it according to the current setting (to the grid, if you haven't changed it). If you specify `no`, no rounding will be done. The other values specify one of the standard kinds of rounding or a custom round-state. Setting the round state with this attribute has no effect except in this instruction: the round state returns to its former value after the instruction is executed. If several <diagonal-stem> instructions use the same round state, it is more efficient to call <set-round-state> before and after that group than to include a `round` attribute with each one. That is also true if the `round` value is to be `no`: in that case call `<set-round-state round-state="no"/>` before and omit the `round` attribute for the <diagonal-stem> instructions.
cut-in
  Whether to use the Control Value cut-in. Legal values are `yes` and `no`; the default is `yes`. If the value of this attribute is `no`, the value of the `round` attribute must also be `no`. (This is a peculiarity of the TrueType instruction set and has nothing to do with Xgridfit.) This attribute has an effect only when a distance is specified.
min-distance
  Whether to maintain a minimum distance between the points in the first line and the points in the second: legal values are `yes` (the default) and `no`.
min-amount
  The value of the minimum-distance setting in pixels. The default value of this setting (1p) is more often than not appropriate for vertical and horizontal stems, but usually needs to be changed for diagonal stems to look their best. This attribute applies only to the present instruction. The minimum-distance setting resumes its former value after this instruction.
color
  Distance type: `black`, `white` or `gray` (the default).
freedom-vector
  Set this to `yes` if you want the Freedom Vector to be the same as the Projection Vector. The default is `no`.
save-vectors
  If `yes`, both the Projection Vector and the Freedom Vector are guaranteed to be the same after this intruction as they were before. The default is `no`.

### <interpolate>

To "interpolate" a point is to move it so that its position relative to two reference points is what it was in the original outline. If the distance between the two reference points is not what it was in the original outline, the point is positioned so that its relationship to the reference points is proportionally correct.

The <interpolate> element must contain at least one point to interpolate. It may contain any number of <point>s and <range>s. Like most other elements that move points, it may contain a <reference> element; but this element must contain two <point>s, not just one.

This instruction may be nested inside a <move> element containing a reference point, or inside a <move> nested in another <move>, and so having an implicit reference point. In an <interpolate> element so placed reference points are needed; the points it contains are automatically interpolated between the <move> element's explicit or implicit reference point and its moved point.

Example:

      <interpolate>
        <reference>
          <point num="top"/>
          <point num="bottom"/>
        </reference>
        <point num="bar-top-left"/>
      </interpolate>

#### Attributes

compile-if
  The <interpolate> instruction is compiled only if the expression in the compile-if attribute evaluates as true (non-zero). The instruction is also compiled if this attribute is omitted.
round
  If this attribute is included with any value other than "no," all points referenced by <point> elements will be aligned to the grid after being interpolated. Points referenced by <range> and <set> elements are unaffected. The possible values of `round` are the same as those for <set-round-state> and <with-round-state>. Note that the value "yes" will use the current round state; so it is usually not necessary to specify a round state here.

### <interpolate-untouched-points>

Interpolates all points that have not been moved or "touched" by instructions so that they are positioned correctly relative to points that have been moved. Most of the time you will want to place this instruction at the end of the program for each glyph.

#### Attribute

axis
  Interpolation always takes place along the x or the y axis. If you omit this attribute, interpolation takes place along both axes.

### <untouch>

A point that has been moved is "touched." This untouches it so that it will be affected by the <interpolate-untouched-points> instruction.

### <align>

Moves one or more points along the freedom vector until aligned with a reference point. Points are "aligned" when their distance from each other, measured along the projection vector, is zero. When the projection vector is "x," aligned points end up stacked vertically; when it is "y" they end up in a horizontal line. When the projection vector is set to a line, the aligned points end up arrayed along an imaginary line orthogonal to the projection vector.

The <align> element must contain at least one point to align. It may contain any number of <point>s and <range>s. An optional <reference> element contains the point to align with. If the reference point is omitted, the current setting of RP0 is used.

The <align> element may be nested in a <move> element, in which case it is not necessary to include a <reference>: the <point> of the parent <move> is implicitly the reference point.

Example:

      <align>
        <reference>
          <point num="left-left-b"/>
        </reference>
        <range ref="knob-range"/>
      </align>

#### Attribute

compile-if
  The <align> instruction is compiled only if the expression in the compile-if attribute evaluates as true (non-zero). The instruction is also compiled if this attribute is omitted.

### <align-midway>

Must contain two <point> elements. Moves these along the freedom vector until they are aligned midway between their original positions. Measurement is along the projection vector.

### <shift>

Shifts one or more points, ranges, contours and zones by the distance between the current position of the reference point and its original position. Note that this does not guarantee that the shifted elements will maintain their original distance from the reference point (use <move> or <mdrp> for that).

The <shift> element may contain points, ranges, contours and zones in any combination and order. The following is perfectly correct:

         <shift>
           <reference>
             <point num="ref-pt"/>
           </reference>
           <point num="move-pt-1"/>
           <range ref="move-rg-1"/>
           <contour num="0"/>
           <point num="move-pt-2"/>
           <range ref="move-rg-2"/>
         </shift>

But note that all the points are shifted first, then all the ranges, then all the contours, and finally any zones. The order of child elements in the <shift> element is not significant; but this is less confusing:

         <shift>
           <reference>
             <point num="ref-pt"/>
           </reference>
           <point num="move-pt-1"/>
           <point num="move-pt-2"/>
           <range ref="move-rg-1"/>
           <range ref="move-rg-2"/>
           <contour num="0"/>
         </shift>

The <shift> element may be nested in a <move> element, in which case it is not necessary to include a <reference>: the <point> of the parent <move> is implicitly the reference point.

#### Attributes

reference-ptr
  Addresses a technical detail: the SHP, SHC and SHZ instructions can use either RP1 or RP2, and this attribute determines which. Chiefly useful if the RP you want to use has already been set; otherwise the default (RP1) should do fine. Xgridfit automatically sets this correctly when a <shift> instruction is nested inside a <move> instruction.
compile-if
  The <align> instruction is compiled only if the expression in the compile-if attribute evaluates as true (non-zero). The instruction is also compiled if this attribute is omitted.
round
  Causes any points referenced by <point> elements to be moved to rounded positions after the shift. <set> and <range> elements are not affected. Works like the `round` attribute on the <interpolate> element.

### <shift-absolute>

Moves one or more points along the freedom vector by a fixed amount (expressed in pixels); it does not use the projection vector. The <shift-absolute> element must contain at least one point to shift: that is, a <range> or a <point> element. It may contain any number of <point>s and <range>s.

#### Attribute

pixel-distance
  The distance (in pixels) to shift the points.

### <move-point-to-intersection>

Moves a point to the intersection of two lines. Each of the lines must be wholly in a single zone, so if specifying the zone use the `zone` attribute of the <line> elements rather than the `zone` attributes of the <point> elements that make up the lines. Example:

      <move-point-to-intersection>
        <point num="pt"/>
        <line>
          <point num="line-a1"/>
          <point num="line-a2"/>
        </line>
        <line>
          <point num="line-b1"/>
          <point num="line-b2"/>
        </line>
      </move-point-to-intersection>

### <set-coordinate>

Moves a <point> to a coordinate determined by the freedom and projection vectors. On the rare occasions when you need a command like this one, it is probably better to use <move> with the `pixel-distance` attribute.

#### Attribute

coordinate
  The new coordinate in pixels.

### <flip-off>
<flip-on>

"Flips" a range of points so that they all become either on-line points or off-line points. The <flip-off> and <flip-on> elements must contain a single <range> element. The range operated upon always runs from the lowest point to the highest. The <range> element may contain a `zone` attribute, in which case the operation takes place in the specified zone.

### <toggle-points>

Any of the points that are on-line become off-line, and any that are off-line become on-line. The <toggle-points> element must contain at least one point to toggle: that is, a <range> or a <point> element. It may contain any number of <point>s and <range>s.

### <mirp>

Corresponds to the MIRP instruction, but attempts, insofar as it is practical, to separate rounding and the cvt cut-in. You can specify `round="no"` and `cut-in="yes"` or both `no` or both `yes`, but not `round="yes"` and `cut-in="no"`. That produces an error-message.

This will take care of setting RP0 beforehand if a reference point is included.

#### Attributes

distance
  distance (from a <control-value> element) relative to the reference point (or to RP0 if that was set by a previous instruction).
round
  whether/how to round the distance. If `yes` is specified, the round bit is set and nothing more is done: so the current round state is used. If `to-grid`, `to-half-grid` or to `to-double-grid`, the round state is set as specified, the instruction is executed, and then the earlier round state is restored. The default is `yes`.
cut-in
  whether to use the cvt cut-in. If rounding is used, this will always be `yes`, even if you set it to `no`.
min-distance
  whether to observe the current minimum distance (1p unless you set it differently using set-minimum-distance). The default is `yes`.
set-rp0
  whether to set reference point 0 to point at the moved point after the instruction is executed. The default value is `no`.
color
  Or distance-type, or compensation for engine characteristics. Whatever. It's got to be gray, black or white, and here gray is the default.

### <mdrp>

Corresponds to the MDRP instruction.

Similar to <mirp>. This will also take care of setting RP0 beforehand if a reference point is supplied.

#### Attributes

round
  Whether/how to round the distance from the reference point.
min-distance
  Whether to maintain a minimum distance from the reference point.
set-rp0
  Whether to set RP0 to the moved point after the move.
color
  Or distance-type, or compensation for engine characteristics. Whatever. It's got to be gray, black or white, and here gray is the default.

### <miap>

Corresponds to the MIAP instruction.

As with mirp, it will try to separate rounding and the cvt cut-in.

Must contain one point element.

#### Attributes

distance
  Distance relative to grid origin
round
  Whether/how to round the distance
cut-in
  Whether to use the cvt cut-in

### <mdap>

Corresponds to the MDAP instruction

Will round a point to the grid if the `round` attribute is not `no`; otherwise will just touch the point (i.e. mark it as moved).

#### Attributes

round
  Whether and how to round