SIL Non-Roman Script Initiative


A free and open rendering engine for complex scripts

Graphite Tutorial

Unit 10: Positioning by shifting



Until now we have discussed only the substitution table, which is used not only for substitution itself but also for insertion and deletion. Now we are going to shift gears and talk about positioning.

Positioning occurs in the positioning table, indicated by the following syntax:

  <rules for positioning>

The positioning table is always run after the substitution table. Like the substitution table, the positioning table can contain multiple passes. The output of the final pass of the substitution table serves as input to the first pass of the positioning table (except if there is a bidi pass, which comes between them; the bidi pass will be covered in a later unit). If you do not include a positioning table in your program, Graphite will automatically include one positioning pass to position glyphs in the standard way.

There are two ways to make adjustments in position: shifting (including kerning) and attachments. In this unit we discuss the shifting and kerning approach.

Shifting and kerning are performed by means of setting the following slot attributes:

  • shift.x
  • shift.y
  • advance.x
  • advance.y
  • kern.x
  • kern.y

The shift attributes adjust the position of the glyph relative to its normal lower-left-hand corner. A positive x value moves the glyph to the right, and a positive y value moves the glyph up. The advance attributes adjust the advance width and height of the glyph, which actually have the effect of changing the position of the following glyph. Keep in mind that setting the shift attributes alone will have no effect on the position of the following glyph. Kerning—shifting the glyph and adjusting the advance width by an equal amount—can be performed by setting the kern attributes, which is actually a short-cut for setting both the shift and advance attributes.

The values of the shift, advance, and kern attributes are expected to be in units that correspond to the size of the em-square on which the font is based. In your GDL program, you can specify the number of units per em-square using the MUnits directive, which can be attached to a table or pass statement as shown:

table(pos) { MUnits = 1000 }

The above statement defines a “virtual em-square” of 1000 units high and 1000 units wide. To specify a value in terms of the defined scale, follow a number with an ‘m’.

shift.x = 500m

The above statement would shift a glyph by half of the width of the font’s em-square. The Graphite compiler scales this number to the actual size of the em-square used in the font, and the engine further scales the resulting number depending on the font size of the text being displayed.

Remember that in the positioning table, because no substitution is occurring, it is not necessary for the rule to include left- and right-hand sides. The syntax is simply:

item1 {<set attributes>}  item2 {<set attributes>}    /  <context>;

and the context part is optional.

Exercise 10a

Write a program to treat all digits as subscripts. Shift them downwards 30% of the size of the font’s em-square. (Don’t worry about changing the size of the digits.)


Exercise 10b

Write a program to kern the uppercase A when it follows W or V, and vice versa (as in “WAVE”). Experiment to determine the best amount by which to kern.


Copyright © 2012 SIL International® and released under the  Creative Commons Attribution-ShareAlike 3.0 license (CC-BY-SA) unless noted otherwise.