Open main menu

TrueType fonts in luaTeX

The following page will provide a short example of what is possible in ConTeXt mkiv. Most of the actual code has been provided by Arthur Reutenauer, to whom I am immensely grateful for his help. The instructions should help you explore some features of luaTeX/mkiv and should inspire you to find your own solutions.

The problem

Newer Windows versions come with a nice Palatino font which I use for my ConTeXt typesetting quite a lot. It has oldstyle figures, real small caps, and a couple of nice additional ligatures. With an OpenType font, luaTeX could just "switch on" this additional stuff by calling the right OpenType features. With an old-fashioned TrueType font, things are a bit less handy. Nevertheless, it is still immensely more convenient than they ever were with pdfTeX. So as an exercise, we will do two things: use some of the ligatures, and use old-style numerals.

The solution: The fea file

fea files tell luaTeX to do something special about a font. In our case, we will create a fea file that tells it to use oldstyle figures and replace some letter combinations by the corresponding ligature. This has to be done in two lua lua tables; the code is easy to understand and write, so even if you have absolutely no experience with lua, you will have no trouble setting this up. So let us begin with the first table. The first wonderful thing about luaTeX is that it can address characters by their unicode value. With pdfTeX, you always had to find out what the name of the character in that particular font was; for luaTeX, it is enough to know that an oldstyle zero is at position F730, oldstyle one at position F731 etc (if you don't know the Adobe glyph list by heart, you can find a reference [here]). This means that our first lua table for the "simple" lookups (one character is replaced with one other character) will look like this:

lookup PalatinoSimple {
    lookupflag 0 ;
	sub zero by uniF730 ;
	sub one by  uniF731 ;
	sub two by uniF732 ;
	sub three by uniF733 ;
	sub four by uniF734 ;
	sub five by uniF735 ;
	sub six by uniF736 ;
	sub seven by uniF737 ;
	sub eight by uniF738 ;
	sub nine by uniF739 ;
} PalatinoSimple ;

This tells luaTeX: please substitute, whenever you encounter the charater zero in the source file, this character witht the character at the unicode position F730, etc.

The next table will contain the "multiple" lookups (two characters are replaced by one character, viz. a ligature). Unfortunately, these ligatures have no fixed Unicode position that would be valid for all fonts, so in this case, it is safer to use the actual character names (which I found out by opening the font in fontforge):

lookup PalatinoMultiple {
    lookupflag 0 ;
	sub f f i by ffi ;
	sub f f l by ffl ;
	sub f i by fi ;
	sub f l by fl ;
	sub f f by ff ;
	sub f t by ft ;
	sub Q u by Qu ;
	sub T h by Th ;
} PalatinoMultiple ;

This table, then, tells luaTeX: whenever an f is followed by an i in the input stream, replace this with the character fi (which happens to be the fi-ligature).

We need to combine these two lookup tables into something that is called a "font feature." These features have to follow certain conventions; they have to have exactly four letters; so let's call it pala for our Palatino font:

feature pala {
    script DFLT ;
	language dflt ;
	    lookup PalatinoMultiple ;
	    lookup PalatinoSimple ;

    script latn;
	language dflt ;
	    lookup PalatinoMultiple ;
	    lookup PalatinoSimple ;
} pala ;

We define this feature both for the "default" and for the "latin" script (I don't know if this is strictly necessary, but go for the "belt and suspenders" approach.)

We save the file with these tables under a name that ends in fea (palatino.fea comes to mind) and put it in a directory under $texmf/fonts/fea/context.

The solution: The typescript file

We now have written the fea file, but we need to instruct ConTeXt to use it. This is done in the typescript. First, we need to make sure that this file and the corresponding typescript will only be used when ConTeXt mkiv is run. So we first write a typescript that is a simple stub. Let's call it type-palatino.tex. It contains just one line:


Which means: when ConTeXt is run, see if it is run as mkii or as mkiv and load the corresponding typescript.

Next, we write the real typescript, type-palatino.mkiv. In it, we have to "install" the font feature pala which we have defined in the fea file, and we have to connect this feature to the fea file. Moreover, we use the font the mkiv way, i.e. we refer to the font by its disk name so luaTeX will directly read and use the TrueType font file, without needing a tfm, as pdfTeX did. The rest is exactly like any ConTeXt typescript:



\starttypescript [serif] [palatino]
  \definefontsynonym [Palatino-Roman]          [name:PalatinoLinotype-Roman]      [features=myfeature]
  \definefontsynonym [Palatino-Bold]           [name:PalatinoLinotype-Bold]       [features=myfeature]
  \definefontsynonym [Palatino-Italic]         [name:PalatinoLinotype-Italic]     [features=myfeature]
  \definefontsynonym [Palatino-Bold-Italic]    [name:PalatinoLinotype-BoldItalic] [features=myfeature]

\starttypescript [serif] [palatino] [name]
  \definefontsynonym [Serif]                   [Palatino-Roman]                   [features=myfeature]
  \definefontsynonym [SerifItalic]             [Palatino-Italic]                  [features=myfeature]
  \definefontsynonym [SerifBold]               [Palatino-Bold]                    [features=myfeature]
  \definefontsynonym [SerifBoldItalic]         [Palatino-Bold-Italic]             [features=myfeature]

\starttypescript [Palatino]
  \definetypeface [Palatino] [rm] [serif] [palatino] [default] 

And that's all! Now you can simply use this palatino font with something like this in your files:


and you'll get the proper ligatures and oldstyle numerals. Defining a small caps Palatino variant is left as an exercise to the reader (hint: small caps characters have names such as Asmall in Palatino, and this is a case for a "simple" lookup table).

To know more

Arthur has been kind enough to provide a few links to official documents from Adobe and Microsoft that explain everything in great detail:

  • 1 The page of the OpenType specification that explains the use of GSUB
  • 2 The page of the Adobe Font Development Kit documentation that describes fea files.
  • 3 The page from the FontForge manual that describes various extensions to the Adobe syntax that are in use by luatex

Good luck with your own experiments!

Thomas 21:51, 8 December 2007 (CET)