该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}