xelatex 的 OTF 字体中无衬线数学宽 П 或 Π?

xelatex 的 OTF 字体中无衬线数学宽 П 或 Π?

我需要一个无衬线数学大写字母,看起来类似于希腊字母 Π 或西里尔字母 П,但垂直条之间有稍多一点的水平空间(假设高度相同),以便根据需要将小拉丁字母“o”放入其中。字母 П,Π(带或不带“o”)将用作函数符号,如 Π(x)=z。STIXNonUnicode-Regular.otf 中的符号编号 0e18c 不够宽,cmunss.otf 中的西里尔字母编号 041F 也不够宽。总的来说,我希望使用 xelatex 进行编译,如果解决方案也可以与 lualatex 一起使用,我会很高兴(即使它涉及对正在运行的引擎进行 if-then-else-fi 检查)。

以下是我迄今为止的尝试:

\documentclass{article}
\usepackage{unicode-math}
%%% General font set-up that fits the rest of the document typographically started.
\setmainfont[
  Extension = .otf,
  UprightFont = *-regular,
  BoldFont = *-bold,
  ItalicFont = *-italic,
  BoldItalicFont = *-bolditalic
]{texgyrepagella}
\setsansfont[
  Extension = .otf,
  UprightFont = *ss,
  BoldFont = *sx,
  ItalicFont = *si,
  BoldItalicFont = *so
]{cmun}
\setmonofont[
  Extension = .otf,
  UprightFont = *-regular,
  BoldFont = *-bold,
  ItalicFont = *-italic,
  BoldItalicFont = *-bolditalic
]{texgyrecursor}
\setmathfont[Extension=.otf]{texgyrepagella-math}
\setmathfont[Extension=.otf,range={\setminus,\mathcal,\mathbfcal,\precneq,\olessthan,\llangle,\rrangle}]{Asana-Math}
\setmathfont[Extension=.otf,range={\smalltriangleleft},BoldFont = *bold]{xits-math}
%%% General font set-up that fits the rest of the document typographically finished.
%%% Now particular junk for the letter in question starts.
\newcommand{\mySymbol}{\textsf{\fontspec{STIXNonUnicode-Regular.otf}\symbol{"0E18C}}}%%% That's similar to what we want. But: in normal size the letter is a little bit too narrow to fit the "o" inside. Also, always puts a normalsize letter :-(.
%\setmathfont[Extension=.otf,
%  BoldFont = cmunsx,
%  ItalicFont = cmunsi,
%  BoldItalicFont = cmunso,
%  range={"041F}
%]{cmunss}%%% Won't work
%\newcommand{\mySymbol}{\textsf{\fontspec{cmunss.otf}\symbol{"041F}}}%%% That's also similar to what we want. But: in normal size the letter is a little bit too narrow to fit the "o" inside. Also, always puts a normalsize letter :-(.
%\newcommand{\mySymbol}{П}%%% Doesn't work at all.
%\newcommand{\mySymbol}{\mathsf{П}}%%% Cyrillic sans-serif П. Doesn't work either.
\newcommand\mySymbolOutputNormal{{%
    \setbox0\hbox{\ensuremath{\mySymbol}}%
    \rlap{\hbox to \wd0{\hss\ensuremath{\scriptstyle\mathrm{o}}\hss}}\box0%
}}
\newcommand\mySymbolOutputScript{{%
    \setbox0\hbox{\ensuremath{\scriptstyle\mySymbol}}%
    \rlap{\hbox to \wd0{\hss\ensuremath{\scriptscriptstyle\mathrm{o}}\hss}}\box0%
}}
\newcommand\mySymbolOutputScriptScript{{%
    \setbox0\hbox{\ensuremath{\scriptscriptstyle\mySymbol}}%
    \rlap{\hbox to \wd0{\hss\ensuremath{\scriptscriptstyle\mathrm{o}}\hss}}\box0%
}}
\newcommand{\mySymbolOutput}{\mathchoice{\mySymbolOutputNormal}{\mySymbolOutputNormal}{\mySymbolOutputScript}{\mySymbolOutputScriptScript}}

\begin{document}
\(\mySymbol(x)_{\mySymbol(y)_{\mySymbol(z)}}\ \mySymbolOutput(x)_{\mySymbolOutput(y)_{\mySymbolOutput(z)}}\)
\[\mySymbol(x)_{\mySymbol(y)_{\mySymbol(z)}}\ \mySymbolOutput(x)_{\mySymbolOutput(y)_{\mySymbolOutput(z)}}\]
\end{document}

在下面的 xelatex 输出中,您会看到此特殊符号在脚本和 scriptscript 中不会缩小。此外,在 normalsize 中没有足够的水平空间容纳“o”。我该如何让这一切正常工作?

使用 xelatex 编译的输出

答案1

我可以建议一种不依赖于引擎的几何结构。

\documentclass{article}
\usepackage{amsmath}
\usepackage{xparse}

\ExplSyntaxOn
\NewDocumentCommand{\sqp}{s}
 {
  \IfBooleanTF{#1}
   {
    \mathord { \mathpalette \egreg_sqp:Nn { \mathrm{o} } }
   }
   {
    \mathord { \mathpalette \egreg_sqp:Nn { } }
   }
 }

\box_new:N \l__egreg_sqp_temp_box
\dim_new:N \l__egreg_sqp_wd_dim % width
\dim_new:N \l__egreg_sqp_ht_dim % height
\dim_new:N \l__egreg_sqp_th_dim % thickness

\cs_new_protected:Nn \egreg_sqp:Nn
 {% #1 = style declaration, #2 = maybe o
  \group_begin:
  \dim_zero:N \mathsurround
  \hbox_set:Nn \l__egreg_sqp_temp_box { $#1\mathrm{o}$ }
  \dim_set:Nn \l__egreg_sqp_wd_dim { \box_wd:N \l__egreg_sqp_temp_box }
  \dim_set:Nn \l__egreg_sqp_th_dim { \box_wd:N \l__egreg_sqp_temp_box/4 }
  \hbox_set:Nn \l__egreg_sqp_temp_box { $#1\Pi$ }
  \dim_set:Nn \l__egreg_sqp_ht_dim { \box_ht:N \l__egreg_sqp_temp_box }

  \mspace{1mu}
  \tl_if_empty:nF { #2 }
   {
    \hbox_to_zero:n
     {
      \hbox_to_wd:nn { \l__egreg_sqp_wd_dim + 2\l__egreg_sqp_th_dim } { \hss $#1#2$ \hss }
      \hss
     }
   }
  \hbox_to_wd:nn { \l__egreg_sqp_wd_dim + 2\l__egreg_sqp_th_dim } { \__egreg_sqp_draw:N #1 \hss }
  \mspace{1mu}
  \group_end:
 }

\cs_new_protected:Nn \__egreg_sqp_draw:N
 {
  \driver_draw_begin:
  \driver_draw_moveto:nn { 0pt } { 0pt }
  \driver_draw_lineto:nn { 0pt } { \l__egreg_sqp_ht_dim }
  \driver_draw_lineto:nn { \l__egreg_sqp_wd_dim + 2\l__egreg_sqp_th_dim } { \l__egreg_sqp_ht_dim }
  \driver_draw_lineto:nn { \l__egreg_sqp_wd_dim + 2\l__egreg_sqp_th_dim } { 0pt }
  \driver_draw_lineto:nn { \l__egreg_sqp_wd_dim + \l__egreg_sqp_th_dim } { 0pt }
  \driver_draw_lineto:nn { \l__egreg_sqp_wd_dim + \l__egreg_sqp_th_dim } { \l__egreg_sqp_ht_dim - 0.7\l__egreg_sqp_th_dim }
  \driver_draw_lineto:nn { \l__egreg_sqp_th_dim } { \l__egreg_sqp_ht_dim - 0.7\l__egreg_sqp_th_dim }
  \driver_draw_lineto:nn { \l__egreg_sqp_th_dim } { 0pt }
  \driver_draw_closepath:
  \driver_draw_fill:
  \driver_draw_end:
 }

\ExplSyntaxOff

\begin{document}

$\Pi\Pi\sqp\Pi\sqp*\Pi\sqp*(x)\sqp(x)$

$\scriptstyle \Pi\Pi\sqp\Pi\sqp*\Pi\sqp*(x)\sqp(x)$

$\scriptscriptstyle \Pi\Pi\sqp\Pi\sqp*\Pi\sqp*(x)\sqp(x)$

\end{document}

在此处输入图片描述

通过简单地改变

\dim_set:Nn \l__egreg_sqp_wd_dim { \box_wd:N \l__egreg_sqp_temp_box }

进入

\dim_set:Nn \l__egreg_sqp_wd_dim { 0.8\box_wd:N \l__egreg_sqp_temp_box }

我们得到

在此处输入图片描述

相关内容