有没有办法可以加快 ucharclasses 的使用速度?

有没有办法可以加快 ucharclasses 的使用速度?

ucharclasses软件包对于基于 Unicode 块的自动字体切换非常有用。但是,它非常非常慢。

加快速度的一种方法是将其范围限制在某些 Unicode 块/脚本上,方法是提供块或块范围作为选项。不幸的是,当遇到在包加载时未选择的块时,这可能会产生负面影响。(另请参阅此处关于我之前问题的讨论:如何使用 ucharclasses 更改特殊脚本的字体,然后恢复到之前的状态?

理想情况下,我希望避免限制ucharclasses某些 Unicode 块并在没有任何选项的情况下加载包。有什么方法可以加快包的使用速度吗?可能通过重写包的部分内容吗?

答案1

设置代码使用了对速度要求极高的代码,ucharclasses速度非常慢。使用...构造大约快 100 倍。我同意它不太干净,但由于我们讨论的是设置每个 Unicode 字符,因此每个文档都需要做大量工作。\forloop\loop\repeat

因此,如果代码是

\newcommand{\@ucc@forloop}[1]
  {\expandafter\@ucc@forloop@\csname c@#1\endcsname}
\newcommand{\@ucc@forloop@}[4]{%
  #1=#2\relax
  \loop
    #4\relax
  \ifnum#1<#3\relax
    \advance#1 by \@ne
  \repeat
}
\newcounter{glyphcounter}
\newcommand{\@defineUnicodeClass}[3]{%
  \newXeTeXintercharclass#1
  \@ucc@forloop {glyphcounter}{#2}{#3}
    {\XeTeXcharclass\value{glyphcounter}=#1}
}

而不是当前的定义\@defineUnicodeClass,即

\newcounter{glyphcounter}
\newcommand{\@defineUnicodeClass}[3]{%
  \newXeTeXintercharclass#1
  %\message{Package ucharclasses Message: #1 was assigned \the#1}
  \forloop{glyphcounter}{#2}{\value{glyphcounter}<#3}{\XeTeXcharclass\value{glyphcounter}=#1}
  \XeTeXcharclass#3=#1}

因此从本质上讲,将该\forloop行改为更快的版本将大大提高设置代码的性能。

然而,我应该警告你,这个软件包的许可证是非自由的,所以我不确定改变你的风格,甚至重命名它,是否合法。

答案2

\fontspec相当慢。如果您使用\setTransitionTo,请改用低级字体命令,这样会快得多。

例子:

\documentclass{article}
\usepackage[Devanagari]{ucharclasses}
\font\mangal="Mangal"
\setTransitionsFor{Devanagari}{\begingroup\mangal}{\endgroup}

\begin{document}
text and ताजा धनिया के साथ अनायास and text
\end{document}

使用低级字体\mangal比使用\fontspec{Arial Unicode MS}或 定义的命令要快得多\newfontfamily。如果你使用了很多这样的转换,那就很清楚了。

但是它与 LaTeX2e 的 NFSS 不兼容,非常糟糕。有关更好的解决方案,请参阅下文。


(适合高级用户)

在 中xeCJK,我们使用了字体缓存机制。可以做类似的事情:当更改为新的 Unicode 块时,通过调用\fontspec和缓存字体\external@font,稍后使用低级命令。

完整代码:

\documentclass{article}
\usepackage[Devanagari]{ucharclasses}
\usepackage{fontspec}
\newfontfamily\mangal{Mangal}

\makeatletter
% inherited from \xeCJK@setfont of xeCJK
\def\sethindifont{% Only one family here, it is simpler than xeCJK
  \ifcsname hindi@\f@series/\f@shape/\f@size\endcsname
    \@nameuse{hindi@\f@series/\f@shape/\f@size}%
  \else
    \mangal
    \get@external@font
    \expandafter\global\expandafter\font
      \csname hindi@\f@series/\f@shape/\f@size\endcsname=\external@font
  \fi}
\makeatother

% proof of code only, should have a loop
% but the code in ucharclasses have too many extra spaces
\def\ResetTransitionTo#1{%
  \XeTeXinterchartoks 255 \csname#1Class\endcsname{\relax}}

\setTransitionsFor{Devanagari}
  {\begingroup\ResetTransitionTo{Devanagari}\sethindifont}
  {\endgroup}

\begin{document}
text and ताजा धनिया के साथ अनायास and text \textbf{and ताजा धनिया के साथ अनायास and text}
\end{document}

相关内容