As of version 2.7 of luaotfload
the support for font feature files (.fea
) has been dropped.
On the ConTeXt mailing list Hans showed how to make font substitution work through Lua. More examples are available in the latest ConTeXt distribution (001,
002,
003,
004,
005,
006,
007)
In the past I have been using font feature files to adjust the kerning of fonts on-the-fly. From Hans' example it is not clear to me how to adjust kerning in the new syntax. The below example does not work as intended.
\documentclass{article}
\usepackage{fontspec}
\directlua{
fonts.handlers.otf.addfeature {
name = "kern",
{
type = "pair",
data = {
[0x0041] = { [0x0056] = { false, { -200, 0, 0, 0 } } },
}
}
}
}
\setmainfont{Latin Modern Roman}
\begin{document}
AV
\end{document}
Can we have a comprehensive guide on how to adjust font features with LuaTeX with the fonts.handlers
technique?
Related questions:
(These involve hooking into the luaotfload.patch_font
callback)
Best Answer
Crimson is useful for experimenting with the new approach, because it’s free and defines few of the features it could support. Here are the features defined in its latest version:
Ligatures
It’s most surprising that
liga
is defined only in the bold italic face, so let’s fix that first.Here’s Crimson before we add the feature:
Now here’s the fix:
In
['f_i'] = { "f", "i" }
,['f_i']
is the glyph name of the ligature, and{ "f", "i" }
are the letters to be ligatured. So if your font calls the ligature ‘fi’ rather than ‘f_i’, you should write['fi'] = { "f", "i" }
. Also note that, in some fonts,['f_f_b'] = { "f", "f", "b" }
doesn’t work, but['f_f_b'] = { "ff", "b" }
does.As Ulrike Fischer explains in tex.stackexchange.com/a/352864 and in her answer to this question, if you have updated
luaotfload
recently (4 February 2017), you will need to revise the invocation of\directlua
as follows:Stylistic and Contextual Alternates
Some alternates are desirable or not depending on what’s nearby. For example, Crimson’s long-tailed ‘Q’ is attractive before ‘u,’ but looks silly or collides with other glyphs if it comes at the end of a word. Compare
salt
, which replaces a glyph by an alternate everywhere, andcalt
, which replaces it in some contexts only:If Crimson had a long-tailed Q in its small caps, you’d get it by adding a line like this:
["q.sc"] = "q.scalt01",
.Superiors
Here I’ve found the principle, or part of it, but it’s probably better not applied to Crimson, because superiors 4–9 and 0 are designed to sit higher than superiors 1–3, as is especially noticeable in note 10 below:
You’ll have to add more such lines (e.g.,
["one.prop"] = "¹",
etc.,) if you want to have footnote figures whether you’re using the default figures, old-style figures, proportional figures, the slashed zero, or any other sort of figure provided.For the
luaotfload
of February 2017, use\directlua
this way:Remove a ligature
Crimson isn’t of much use to illustrate removal of ligatures, so here’s FPL Neu (github.com/rstub/fplneu) without its ‘fk’ ligature:
The result is hardly visible in a font like Garamond Premier Pro, with its long-armed f, and I can’t seem to combine this
nofk
feature with extra kerning.For the
luaotfload
of February 2017, use\directlua
this way:Select among standard ligatures
Some fonts put more in their
liga
feature than one could wish. For example, LTC Kaatskill Pro, a lovely Goudy design, makes œ a standard rather than a discretionary ligature, with the result that not only words like ‘œdema’ but even ‘does’ and ‘poem’ are affected. Usingtype = "multiple"
, as for ‘fk’ above, would fix ‘does’ but interfere with ‘œdema,’ so we need another approach.To illustrate, let’s examine a freely available Carolingian minuscule. With
liga
, it produces results one could use to ease students into a paleography course:For decorative rather than scholarly purposes, we’d want to remove whatever is defined in
liga
but unfamiliar to contemporary readers.Besides the harmless ‘ff,’ ‘fi,’ ‘fl,’ ‘ft,’ and ‘ll,’
liga
adds an ‘oe’ ligature and e caudata for ‘ae’; it also replaces ‘i’ and ‘j’ with their dotless versions, and substitutes ‘ſ’ for ‘s,’ ‘u’ for ‘v,’ and ‘V’ for ‘U.’ We can remove those ligatures and substitutions by turning offliga
, and add back the harmless ligatures by defining them asrlig
, a feature which is on by default:Stubborn fonts
Sometimes one or more ligatures don’t work, and adding them as above doesn’t help. This happens when a font’s lookups define the ligatures in the wrong order, as Khaled Hosny remarks. Fixing the problem without editing the font itself can be quite difficult if the lookups are especially complex, but often there’s no need to edit the font.
For example, Goudy’s Newstyle defines ‘fi’ and ‘fl’ in its
liga
feature, and slightly different ‘fi’ and ‘fl’ glyphs in itsdlig
feature. There are also glyphs for ‘ct,’ ‘fb,’ ‘ff,’ ‘ffi,’ ‘fj,’ ‘ffl,’ ‘fk,’ ‘st,’ and (in the italic) ‘Th,’ but no feature is defined to ease their use. Adding the two-character ligatures toliga
works, but adding the ‘ffi’ and ‘ffl’ ligatures doesn’t, apparently because the ‘fi’ and ‘fl’ ligatures are already in the lookup. But all is well if we turn offliga
and define the ligatures we want asrlig
:If a font’s
liga
feature contains many ligatures, it’s easier to keepliga
on, break up only the problematic ligatures, and then restore them inrlig
. For example, this produces the same output as above:CAVEAT
I don’t really understand what I’ve done, and there may be better ways (which I’d be glad to learn about), but at least things are more or less working.
ADDENDUM
With some trepidation, I’ve created my first (and probably last) GitHub repository, where I’ll gradually put notes on fonts I’ve tried to fix. That should prevent this answer from becoming cluttered with discussions of typefaces to which few have access, save others with the same fonts from duplicating my labor, and perhaps allow for joint discovery of more satisfactory solutions.