为 LuaLaTeX 中缺失的字形定义后备字体

为 LuaLaTeX 中缺失的字形定义后备字体

我想使用“Hack”作为源代码的默认字体。不幸的是,该字体缺少我使用的某些字形。如果我使用“Hack”中缺少的字形,我希望它自动以另一种字体(例如“Symbola”)显示。

\documentclass{article}
\usepackage{fontspec}
\usepackage{verbatim}
\setmonofont{Hack}
%\setmonofont{Symbola} % use Symbola if glyph is missing in Hack
\begin{document}
\begin{verbatim}
- 

答案1

这是我能想到的:

\documentclass{article}
\usepackage{fontspec}
\setmonofont{Hack}
\usepackage{verbatim}

\newfontface\Symbola{Symbola}
{\Symbola\global\expandafter\let\expandafter\fallbackfont\the\font}
\usepackage{luacode}
\begin{luacode}
local fontcharacters = { }
local nullfont       = 0
local glyph_t        = nodes.nodecodes.glyph
local fallbackfont   = font.id("fallbackfont")
table.setmetatableindex(fontcharacters, function (t, k)
  if k == true then
    return fontcharacters[currentfont()]
  else
    local tfmdata = fonts.hashes.identifiers[k]
    if not tfmdata then --- unsafe
      tfmdata = font.fonts[k]
      if not (tfmdata and type (tfmdata) == "table") then
        return false
      end
    end
    local characters = tfmdata.characters
    t[k] = characters
    return characters
  end
end)
local nodeprocessor = function (head)
  local lastfont, characters = nil, nil
  for n in node.traverse_id(glyph_t, head) do
    local currfont = n.font
    local char = n.char
    if currfont ~= lastfont and currfont ~= nullfont then
      characters = fontcharacters[currfont]
    end
    if characters ~= false then
      lastfont = currfont
      if not characters[char] then
        n.font = fallbackfont
        if fontcharacters[fallbackfont][char] then
          node.remove(head,node.next(n)) -- remove .notdef char (new in luaotfload 2.98)
        end
      end
    end
  end
  return head, false
end
luatexbase.add_to_callback("pre_linebreak_filter", nodeprocessor, "replace missing glyphs")
\end{luacode}

\begin{document}
\begin{verbatim}
- 

答案2

虽然这不使用fontspec,但您可以使用 Ulrike Fischer 的实验combofont包。这使用了luaotfload的内置字体组合支持:

\documentclass{article}
\usepackage{verbatim}
\usepackage{combofont}
% Define a combofont for every font in the family
\setupcombofont{hack-symbola-regular}{
  {Hack:\combodefaultfeat} at #1pt,
  {Symbola:\combodefaultfeat} at #1pt
}{
  {},
  fallback
}

\setupcombofont{hack-symbola-bold}{
  {Hack/B:\combodefaultfeat} at #1pt,
  {Symbola:\combodefaultfeat} at #1pt
}{
  {},
  fallback
}

\setupcombofont{hack-symbola-italic}{
  {Hack/I:\combodefaultfeat} at #1pt,
  {Symbola:\combodefaultfeat} at #1pt
}{
  {},
  fallback
}

\setupcombofont{hack-symbola-bolditalic}{
  {Hack/BI:\combodefaultfeat} at #1pt,
  {Symbola:\combodefaultfeat} at #1pt
}{
  {},
  fallback
}

% Now set up the family
\DeclareFontFamily{TU}{hack-symbola}{}
\DeclareFontShape{TU}{hack-symbola}{m}{n} {<->combo*hack-symbola-regular}{}
\DeclareFontShape{TU}{hack-symbola}{bx}{n} {<->combo*hack-symbola-bold}{}
\DeclareFontShape{TU}{hack-symbola}{m}{it} {<->combo*hack-symbola-italic}{}
\DeclareFontShape{TU}{hack-symbola}{bx}{it} {<->combo*hack-symbola-bolditalic}{}
\renewcommand \ttdefault {hack-symbola}

\begin{document}
\begin{verbatim}
- 

相关内容