覆盖 `\bfseries` 和 `\itshape` 来为某些家族做特殊的事情

覆盖 `\bfseries` 和 `\itshape` 来为某些家族做特殊的事情

我的问题源于尝试解决问题 26276:我想使用 SizeFeatures 明确选择另一个字体系列以适应小尺寸,但这会导致粗体/斜体/等在小尺寸下停止工作。我的解决方案是重新定义\bfseries\itshape为每个变体实际使用一种新字体,但无论实际使用哪种字体系列,都会应用此解决方法……如果我想在文档中使用多个(真实)字体系列,这会导致问题。

问题。我如何可靠地测试当前的字体系列,以便我的代码可以决定是否应用解决方法?

这里是一些示例代码:

\documentclass[12pt,a4paper]{article}
\usepackage{fontspec}
\usepackage{etoolbox}
\setmainfont[%
SizeFeatures={%
  {Size=-10, Font={Georgia}}, %
  {Size=10-}%
}]{Times}

\newfontface\boldface[%
SizeFeatures={%
  {Size=-10, Font={Georgia Bold}}, %
  {Size=10-}%
}]{Times Bold}

\newfontface\italicface[%
SizeFeatures={%
  {Size=-10, Font={Georgia Italic}}, %
  {Size=10-}%
}]{Times Italic}

\newfontface\bolditalicface[%
SizeFeatures={%
  {Size=-10, Font={Georgia Bold Italic}}, %
  {Size=10-}%
}]{Times Bold Italic}

\setsansfont{Helvetica}

\DeclareTextFontCommand{\textbfit}{\bfseries\itshape}

\ExplSyntaxOn
\makeatletter
\let\int@bfseries\bfseries
\let\int@itshape\itshape

\renewcommand{\bfseries}{\str_if_eq_x:nnTF \f@shape \itdefault
  {\bolditalicface \int@bfseries\int@itshape}
  {\boldface \int@bfseries}
}
\renewcommand{\itshape}{\str_if_eq_x:nnTF \f@series \bfdefault
  {\bolditalicface \int@bfseries\int@itshape}
  {\italicface \int@itshape}
}
\makeatother
\ExplSyntaxOff

\begin{document}
\noindent
{\normalfont Roman: Normal \textit{Italic} \textbf{Bold} \textbfit{Bold Italic} \textit{\bfseries Italic Bold}} \newline
{\scriptsize Roman: Normal \textit{Italic} \textbf{Bold} \textbfit{Bold Italic} \textit{\bfseries Italic Bold}} \newline
{\sffamily Sans: Normal \textit{Italic} \textbf{Bold} \textbfit{Bold Italic} \textit{\bfseries Italic Bold}} \newline
{\sffamily\scriptsize Sans: Normal \textit{Italic} \textbf{Bold} \textbfit{Bold Italic} \textit{\bfseries Italic Bold}} \newline
\end{document}

答案1

我刚刚发现我可以用来xstring测试字符串前缀。我的这个版本的解决方法似乎更强大:

\documentclass[12pt,a4paper]{article}
\usepackage{fontspec}
\usepackage{xstring}
\setmainfont[%
SizeFeatures={%
  {Size=-10, Font={Georgia}}, %
  {Size=10-}%
}]{Times}

\newfontfamily\boldface[%
BoldFont={Times Bold}, %
SizeFeatures={%
  {Size=-10, Font={Georgia Bold}}, %
  {Size=10-}%
}]{Times Bold}

\newfontfamily\italicface[%
ItalicFont={Times Italic}, %
SizeFeatures={%
  {Size=-10, Font={Georgia Italic}}, %
  {Size=10-}%
}]{Times Italic}

\newfontfamily\bolditalicface[%
BoldItalicFont={Times Bold Italic}, %
SizeFeatures={%
  {Size=-10, Font={Georgia Bold Italic}}, %
  {Size=10-}%
}]{Times Bold Italic}

\setsansfont{Helvetica}

\DeclareTextFontCommand{\textbfit}{\bfseries\itshape}

\ExplSyntaxOn
\makeatletter
\let\int@bfseries\bfseries
\let\int@itshape\itshape
\let\int@upshape\upshape

\renewcommand{\bfseries}{\IfBeginWith{\f@family}{Times}
  {\str_if_eq_x:nnTF \f@shape \itdefault
    {\bolditalicface \int@bfseries\int@itshape}
    {\boldface \int@bfseries}
  }{\int@bfseries}
}
\renewcommand{\itshape}{\IfBeginWith{\f@family}{Times}
  {\str_if_eq_x:nnTF \f@series \bfdefault
    {\bolditalicface \int@bfseries\int@itshape}
    {\italicface \int@itshape}
  }{\int@itshape}
}
\renewcommand{\upshape}{\IfBeginWith{\f@family}{Times}
  {\str_if_eq_x:nnTF \f@series \bfdefault
    {\boldface \int@bfseries\int@upshape}
    {\normalfont \int@upshape}
  }{\int@itshape}
}

\let\emshape\itshape
\let\eminnershape\upshape
\makeatother
\ExplSyntaxOff

\begin{document}
\emph{Emphasis with \emph{inner emphasis and \emph{inner-inner emphasis}}, plus {\upshape upright}.}

{\scriptsize \emph{Emphasis with \emph{inner emphasis and \emph{inner-inner emphasis}}, plus {\upshape upright}.}}

\bigskip\noindent
{\normalfont Roman: Normal \textit{Italic} \textbf{Bold} \textbfit{Bold Italic} \textit{\bfseries Italic Bold}}

\noindent
{\scriptsize Roman: Normal \textit{Italic} \textbf{Bold} \textbfit{Bold Italic} \textit{\bfseries Italic Bold}}

\noindent
{\sffamily Sans: Normal \textit{Italic} \textbf{Bold} \textbfit{Bold Italic} \textit{\bfseries Italic Bold}}

\noindent
{\sffamily\scriptsize Sans: Normal \textit{Italic} \textbf{Bold} \textbfit{Bold Italic} \textit{\bfseries Italic Bold}}
\end{document}

相关内容