[Tex/LaTex] Historic font and missing ligatures

fontspecligatures

I am trying to compose a sort of old-style book. I would like to use a specific historical font for the entire text. This font includes ligature glyphs for: ff, fi, fl, ffl, and st (see Figure 1 for the italic style).

Map of characters

Unfortunately, XeLaTeX and LuaLaTeX seem not to recognize the presence of ligatures. I tried the following simple code.

% !TEX TS-program = xelatex
\documentclass{article}
\usepackage{fontspec}
\setmainfont[Ligatures={Required,%
Common,Contextual,Rare,Historic,TeX}]{Historical-FellTypeItalic}

\begin{document}
ff fi fl ffl st
\end{document}

Unfortunately, the LaTeX result is without ligatures (the same occurs with the light style of the font). On the other hand, different fonts (e.g. Linux Libertine) work correctly. I tried also to install the font in LaTeX system but I did not obtain any result (the font works but not the ligatures).

Do you know any solution?

Another (and secondary) question. Some interesting glyph (as ct, us, and as) are present. I have no idea, how to integrate them in the LaTeX code. I would like to type words using those glyphs without particular declarations.

For your information: I use a fully updated TeXLive on Windows 10 (x64).


EDIT

Thanks for all answers. It works fine, but I would deepen the matter with the LuaLaTeX code.
If I had more than a single font in use (e.g. ITALIC.otf and ROMAN.otf), how could I have adapted the Lua-code for lacking glyphs in different fonts?
Let me explain through an example:
The ligature glyph is (uchar(916)) exists for ITALIC.otf but not for ROMAN.otf. In this way, the simplify code:

% all your LuaLaTeX-code
\usepackage{fontspec}
\setmainfont[ItalicFont=ITALIC.otf]{ROMAN.otf}
\begin{document}
is \textit{is}
\end{document}

produces a PDF uniquely with the italic is (the roman is is missed). I suppose, that LaTeX tries to search the ROMAN glyph uchar(916) instead of inserting the ROMAN glyphs of i and s.
Do a solution exist? Thanks again for your attention.

Best Answer

The problem with this font -- as far as its ligatures are concerned -- is that the ligature names in the internal font table are, shall we say, utterly non-standard. For instance, instead of going with standard names such as f_f and f_f_i for the ligatures, a search with the FontForge app reveals that the font uses the names Omega and approxequal. No joke!! (A not-uncharitable assessment of the situation might be that the font's name correspondence table got garbled at some point prior to compilation.)

Given this situation, it's probably not a surprise that LuaLaTeX and XeLaTeX are not able to figure out the name mappings without special help.

Using LuaLaTeX, I can think of two solutions to this mess. The first solution creates a custom "feature file", which informs the system about the ligature names actually used by the font. The second, shown further below, uses LuaTeX functionality directly to get the ligatures working.


With the help of FontForge I was able to find the "names" for all ten ligatures. These names are used to set up a so-called "Feature File", named addligs_HFTI.fea, that can be loaded via an instruction such as \addfontfeatures{FeatureFile=addligs_HFTI.fea}.

Unfortunately, despite having found the font's ligature "names" for all ten ligatures, this approach succeeds in activating only four of them (ct, ff, ffi, and ffl, to be specific). Maybe something else got garbled as well when the font was compiled?

enter image description here

% !TEX TS-program = lualatex

\RequirePackage{filecontents}
\begin{filecontents*}{addligs_HFTI.fea}
languagesystem DFLT dflt;
languagesystem latn dflt;
# Ligatures
feature liga {
    sub a s   by summation;
    sub i s   by Delta;
    sub u s   by divide;
    sub c t   by plusminus;
    sub f f   by Omega;
    sub f i   by fi;
    sub f l   by fl;
    sub f f i by approxequal;
    sub f f l by radical;
} liga;
\end{filecontents*}

\documentclass{article}
\newcommand\liglist{as is ct ff fi fl ffi ffl}
\usepackage{fontspec}
\defaultfontfeatures{Ligatures=Common}
\setmainfont{Historical-FellTypeItalic}

\begin{document}
w/o ligatures: \liglist

\addfontfeatures{FeatureFile=addligs_HFTI.fea}
with ligatures: \liglist
\end{document}

Addendum. Given that the feature file approach doesn't succeed in activating all ten ligatures present in the font, the following solution, which is entirely coded in Lua, may be worth considering. It uses the process_input_buffer callback to run a function that performs a "brute force" substitution of the ten character pairs and triples with the corresponding glyphs that represent the ligated versions. (Full disclosure: The code used below gratefully uses code originally provided by @michal.h21 in his answer to my recent posting, entitled LuaLaTeX: How to use a \char directive inside a string.gsub function?) Observe that special care had to be taken to ensure that any LaTeX macros that may include strings such as "ff", "fi", etc aren't caught up in the brute-force substitution.

enter image description here

% !TEX TS-program = lualatex
\documentclass{article}
\usepackage{fontspec}
\setmainfont{Historical-FellTypeItalic}

\usepackage{luacode,luatexbase} 
\begin{luacode}
local uchar = unicode.utf8.char
function ligsub ( s )
  local x = s:gsub('(\\?)([%a%@]+)', 
        function(back,text)
            if back~="" then 
               return back .. text  
            end
            text = text:gsub ( 'ffi', uchar(8776)) 
            text = text:gsub ( 'ffl', uchar(8730))
            text = text:gsub ( 'ff',  uchar(937))
            text = text:gsub ( 'fi',  uchar(64257))
            text = text:gsub ( 'fl',  uchar(64258))
            text = text:gsub ( 'as',  uchar(8721))
            text = text:gsub ( 'is',  uchar(916))
            text = text:gsub ( 'us',  uchar(247))
            text = text:gsub ( 'ct',  uchar(177))
            text = text:gsub ( 'st',  uchar(9674))
            return text
       end)
  print("x", x)
  return x
end
\end{luacode}
\AtBeginDocument{% 
    \directlua{luatexbase.add_to_callback (         
              "process_input_buffer", ligsub, "ligsub" )}}

\newcommand\off{off}  % dummy macro (see below)

\begin{document}
off fit fly office baffle

as is us act step

\off --note: no ff-ligature
\end{document}

Remark: The only downside I can see to taking this approach is that it's definitely going to mess up the work of a screen-reader: eight of the ten ligatures -- those for ff, ffi and fl, as, is, us, ct, and st -- get rendered as Ω, , , Σ, Δ, ±, and , respectively. Argghh. (In contrast, fi and fl do get rendered correctly; probably not coincidentally, those are the two ligatures that have a "normal" name in the feature file, which was shown earlier.) That's not really the fault of the LuaLaTeX-based approach, though; rather, the font's messed-up name tables are to blame. Ideally, the authors and/or maintainers of the font would re-release it, this time with the name table cleaned up drastically.

Related Question