[Tex/LaTex] Can’t generate ligatures with LuaLaTeX under MacTeX2014 and MacTeX2015 when using certain fonts

fontsligaturesluatexmacopentype

(Remark: This question was posted originally when the big news, TeX-wise, was the impending transition from TeXLive2013 to TeXLive2014. Since the issue identified in this posting persists in TeXLive2015, I've chosen to update the posting's title accordingly.)

Consider the following MWE:

% !TEX TS-program = lualatex
\documentclass{article}
\listfiles
\usepackage{fontspec}
\setmainfont[Ligatures={Common,Rare}]{Hoefler Text}
\begin{document}
ff fi fl ffi ffl fj ct st
\end{document}

When compiling this program on my system (MacOSX 10.9.2, MacTeX2013, luatex 0.76.0) under LuaLaTeX, I get the expected result, i.e., all ligatures are generated correctly:

enter image description here

However, if I switch to TeXLive2014 (currently in advanced beta), which employs luatex 0.79.1, no ligatures are created:

enter image description here

This problem doesn't arise under TeXLive2014 if I (i) compile the MWE under XeLaTeX instead of LuaLaTeX or (ii) use a different font, say, Adobe Garamond Pro, Garamond Premier Pro, or Latin Modern Roman. (Of course, the latter font doesn't feature ligatures for fj, ct, and st, but ligatures are generated for ff, fi, fl, ffi, and ffl.)

Is there a setting that needs to be tweaked to enable ligatures when using Hoefler Text?

For completeness, here are the files used by the LuaLaTeX/TeXLive2014 run:

LuaTeX, Version beta-0.79.1 (TeX Live 2014/dev) (rev 4971)  (format=lualatex 2014.4.24) 

 *File List*
 article.cls    2007/10/19 v1.4h Standard LaTeX document class
  size10.clo    2007/10/19 v1.4h Standard LaTeX file (size option)
fontspec.sty    2013/05/20 v2.3c Font selection for XeLaTeX and LuaLaTeX
   expl3.sty    2014/01/07 v4646 L3 Experimental code bundle wrapper
 l3names.sty    2014/01/04 v4640 L3 Namespace for primitives
l3bootstrap.sty    2014/01/04 v4640 L3 Experimental bootstrap code
  luatex.sty    2010/03/09 v0.4 LuaTeX basic definition package (HO)
infwarerr.sty    2010/04/08 v1.3 Providing info/warning/error messages (HO)
ifluatex.sty    2010/03/01 v1.3 Provides the ifluatex switch (HO)
    etex.sty    1998/03/26 v2.0 eTeX basic definition package (PEB)
luatex-loader.sty    2010/03/09 v0.4 Lua module loader (HO)
pdftexcmds.sty    2011/11/29 v0.20 Utility functions of pdfTeX for LuaTeX (HO)
 ltxcmds.sty    2011/11/09 v1.22 LaTeX kernel commands for general use (HO)
   ifpdf.sty    2011/01/30 v2.3 Provides the ifpdf switch (HO)
l3basics.sty    2014/01/04 v4642 L3 Basic definitions
 l3expan.sty    2014/01/04 v4642 L3 Argument expansion
    l3tl.sty    2013/12/27 v4625 L3 Token lists
   l3seq.sty    2013/12/14 v4623 L3 Sequences and stacks
   l3int.sty    2013/08/02 v4583 L3 Integers
 l3quark.sty    2013/12/14 v4623 L3 Quarks
   l3prg.sty    2014/01/04 v4642 L3 Control structures
 l3clist.sty    2013/07/28 v4581 L3 Comma separated lists
 l3token.sty    2013/08/25 v4587 L3 Experimental token manipulation
  l3prop.sty    2013/12/14 v4623 L3 Property lists
   l3msg.sty    2013/07/28 v4581 L3 Messages
  l3file.sty    2013/10/13 v4596 L3 File and I/O operations
  l3skip.sty    2013/07/28 v4581 L3 Dimensions and skips
  l3keys.sty    2013/12/08 v4614 L3 Experimental key-value interfaces
    l3fp.sty    2014/01/04 v4642 L3 Floating points
   l3box.sty    2013/07/28 v4581 L3 Experimental boxes
l3coffins.sty    2013/12/14 v4624 L3 Coffin code layer
 l3color.sty    2012/08/29 v4156 L3 Experimental color support
l3luatex.sty    2013/07/28 v4581 L3 Experimental LuaTeX-specific functions
l3candidates.sty    2014/01/06 v4643 L3 Experimental additions to l3kernel
  xparse.sty    2013/12/31 v4634 L3 Experimental document command parser
luaotfload.sty    2014/02/05 v2.4-3 OpenType layout system
luatexbase.sty    2013/05/11 v0.6 Resource management for the LuaTeX macro progr
ammer
luatexbase-compat.sty    2011/05/24 v0.4 Compatibility tools for LuaTeX
luatexbase-modutils.sty    2013/05/11 v0.6 Module utilities for LuaTeX
luatexbase-loader.sty    2013/05/11 v0.6 Lua module loader for LuaTeX
luatexbase-regs.sty    2011/05/24 v0.4 Registers allocation for LuaTeX
luatexbase-attr.sty    2013/05/11 v0.6 Attributes allocation for LuaTeX
luatexbase-cctb.sty    2013/05/11 v0.6 Catcodetable allocation for LuaTeX
luatexbase-mcb.sty    2013/05/11 v0.6 Callback management for LuaTeX
fontspec-patches.sty    2013/05/20 v2.3c Font selection for XeLaTeX and LuaLaTeX

fixltx2e.sty    2006/09/13 v1.1m fixes to LaTeX
fontspec-luatex.sty    2013/05/20 v2.3c Font selection for XeLaTeX and LuaLaTeX
 fontenc.sty
  eu2enc.def    2010/05/27 v0.1h Experimental Unicode font encodings
  eu2lmr.fd    2009/10/30 v1.6 Font defs for Latin Modern
xunicode.sty    2011/09/09 v0.981 provides access to latin accents and many othe
r characters in Unicode lower plane
 eu2lmss.fd    2009/10/30 v1.6 Font defs for Latin Modern
graphicx.sty    1999/02/16 v1.0f Enhanced LaTeX Graphics (DPC,SPQR)
  keyval.sty    1999/03/16 v1.13 key=value parser (DPC)
graphics.sty    2009/02/05 v1.0o Standard LaTeX Graphics (DPC,SPQR)
    trig.sty    1999/03/16 v1.09 sin cos tan (DPC)
graphics.cfg    2010/04/23 v1.9 graphics configuration of TeX Live
  pdftex.def    2011/05/27 v0.06d Graphics/color for pdfTeX
fontspec.cfg
   t3cmr.fd    2001/12/31 TIPA font definitions
supp-pdf.mkii
epstopdf-base.sty    2010/02/09 v2.5 Base part for package epstopdf
  grfext.sty    2010/08/19 v1.1 Manage graphics extensions (HO)
kvdefinekeys.sty    2011/04/07 v1.3 Define keys (HO)
kvoptions.sty    2011/06/30 v3.11 Key value format for package options (HO)
kvsetkeys.sty    2012/04/25 v1.16 Key value parser (HO)
etexcmds.sty    2011/02/16 v1.5 Avoid name clashes with e-TeX commands (HO)
epstopdf-sys.cfg    2010/07/13 v1.3 Configuration of (r)epstopdf for TeX Live
 ***********

Best Answer

With the advent of MacTeX2014 and continuing in MacTeX2015 -- and likely to persist into the indefinite future :-( -- Lua(La)TeX can no longer directly access certain font features, such as ligatures, if the font is a system font whose ligature-related properties are AAT-encoded and not OpenType-encoded. Hoefler Text, Didot, and Baskerville are three such fonts. (In contrast, XeLaTeX continues to be able to access ligature-related features directly.)

By setting up one more or "feature files" that spell out which ligature substitutions should be performed, it is possible to restore ligatures when working with version of LuaLaTeX more recent than version 0.77.

The output of the code shown below has the following characteristics: the first row is generated before the feature file is loaded; note that it's lacking ligatures even though the option Ligatures=Common option was specified when the font (Hoefler Text in this case) was loaded via a \setmainfont statement. The second row, which is generated after the feature file is loaded via an \addfontfeature instruction, contains all the expected ligatures.

Aside: (i) The example uses the filecontents package to be self-contained. In practice, all one needs to do is to create the feature file "addligs.fea" once and store it in a directory that's searched by the TeX distribution. (ii) The feature file shown here features (pun intended...) quite a few ligature substitutions, since Hoefler Text features lots and lots of ligatures. For other, less feature-rich, fonts, the "standard five" ligatures -- ff, fi, fl, ffi, and ffl -- may be all that you need to take of.

enter image description here

% !TEX TS-program = lualatex

\RequirePackage{filecontents}
\begin{filecontents*}{addligs.fea}
languagesystem DFLT dflt;
languagesystem latn dflt;
# Ligatures
feature liga {
    sub f f   by f_f;
    sub f i   by f_i;
    sub f j   by f_j;
    sub f k   by f_k;
    sub f l   by f_l;
    sub f f i by f_f_i;
    sub f f l by f_f_l;
    sub s t   by s_t;
    sub c t   by c_t;
} liga;
\end{filecontents*}

\documentclass{article}
\usepackage{fontspec}
\setmainfont[Ligatures=Common]{Hoefler Text}

\newcommand\wordlist{off fit fjord Kafka fly office baffle stop act}

\begin{document}
\wordlist

\addfontfeature{FeatureFile=addligs.fea}
\wordlist
\end{document}

Addendum: Here's a slightly more sophisticated example, which uses two different feature files depending on whether the font face is upright or italic. It makes use of the ability of fontspec to specify different features for Upright, Bold, Italic, and BoldItalic font faces. The separate treatment of the italic and non-italic cases is necessary because Hoefler Text features additional ligatures (esp. for "sp" and "Th") just for the italic font faces.

enter image description here

% !TEX TS-program = lualatex

\RequirePackage{filecontents}

\begin{filecontents*}{AddligsHoeflerUpright.fea}
languagesystem DFLT dflt;
languagesystem latn dflt;
# Ligatures
feature liga {
    sub f b   by f_b;
    sub f f   by f_f;
    sub f h   by f_h;
    sub f i   by f_i;
    sub f j   by f_j;
    sub f k   by f_k;
    sub f l   by f_l;
    sub f f b by f_f_b;
    sub f f h by f_f_h;
    sub f f i by f_f_i;
    sub f f k by f_f_k;
    sub f f l by f_f_l;
    sub c t   by c_t;
    sub s t   by s_t;
} liga;
\end{filecontents*}

\begin{filecontents*}{AddligsHoeflerItalic.fea}
languagesystem DFLT dflt;
languagesystem latn dflt;
# Ligatures
feature liga {
    sub f b   by f_b;
    sub f f   by f_f;
    sub f h   by f_h;
    sub f i   by f_i;
    sub f j   by f_j;
    sub f k   by f_k;
    sub f l   by f_l;
    sub f f b by f_f_b;
    sub f f h by f_f_h;
    sub f f i by f_f_i;
    sub f f k by f_f_k;
    sub f f l by f_f_l;
    sub c t   by c_t;
    sub s t   by s_t;
    sub s p   by s_p;
    sub T h   by T_h;
    sub a s   by a_s;
} liga;
\end{filecontents*}

\documentclass{article}
\usepackage{fontspec}
\setmainfont{Hoefler Text}[
    Ligatures          = {Common,Rare},
    ItalicFont         = Hoefler Text Italic,
    BoldFont           = Hoefler Text Black,
    BoldItalicFont     = Hoefler Text Black Italic]

\newcommand\words{fb ff fh fi fj fk fl ffb ffh ffk ffl ct st, sp Th}

\begin{document}

ligatures missing:

\words\par
\textbf{\words}\par
\textit{\words}\par
\textbf{\textit{\words}}

\addfontfeature{%
    UprightFeatures    = {FeatureFile=AddligsHoeflerUpright.fea},
    BoldFeatures       = {FeatureFile=AddligsHoeflerUpright.fea},
    ItalicFeatures     = {FeatureFile=AddligsHoeflerItalic.fea},
    BoldItalicFeatures = {FeatureFile=AddligsHoeflerItalic.fea}}

\medskip   
ligatures restored/activated:

\words\par
\textbf{\words}\par
\textit{\words}\par
\textbf{\textit{\words}}

\end{document}
Related Question