使用 XeTeXinterchartoks 时如何知道两个字符之间的宽度并填充粘合空间

使用 XeTeXinterchartoks 时如何知道两个字符之间的宽度并填充粘合空间

我正在尝试使用 Xetexinterchartoks 将粘连空间替换为 Xetex 中字形的拉伸版本。以下是示例:

\documentclass[10pt,a4paper]{article}
\usepackage{graphicx}
\newcommand \stretchit{
    \makeatletter   
    \XeTeXinterchartokenstate 1%
    \newXeTeXintercharclass \mycharclassA%
    \newXeTeXintercharclass \mycharclassB%
    \XeTeXcharclass `\A \mycharclassA
    \XeTeXcharclass `\B \mycharclassB   
    \chardef\mylinechar=`= %
    \def\mystretchedchar{%
    \nobreak%
    \leavevmode%
        %MainScenario 
        %\dimen0=\XeTeXglyphbounds2 \the\XeTeXcharglyph\mylinechar%"0640%
        %\dimen1=\XeTeXglyphbounds4 \the\XeTeXcharglyph\mylinechar%"0640
        %\leaders\hrule height \dimen0 depth \dimen1 \hskip 0pt plus 05.em%
        %Alternative Scenario #1 
        \hskip 0pt plus 05.em %
        \dimen0=\lastskip%
        \unskip   
        \typeout{DIMEN2= \the\dimen0***and last skip=\the\lastskip }%
        %Alternative Scenario #2
        \setbox0=\hbox{\leaders\hrule height \dimen0 depth \dimen1 \hskip 0pt plus 05.em} %testing: hfil,   
        \dimen0=\wd0%      
        %The actual drawing
        \typeout{DIMEN2= \the\dimen0***and last skip=\the\lastskip }%
        \resizebox{\dimen0}{\height}{\mylinechar}% this: \clipbox{0pt}{\mylinechar} might clip some strange whitespaces around the glyph
    \makeatother
    }
    \XeTeXinterchartoks \mycharclassA \mycharclassB = {\mystretchedchar}

}
\begin{document}
\stretchit{}
Test test test testABTest test test testTestTesttesttest testTest test test test test test test
\end{document}

但是胶水宽度总是报告为零,而输出中当然不为零。我猜这可能是因为我在计算胶水宽度时它仍然为零。

可以\hrule用多个字符(或像 MainScenario 中那样的一行)填充空间,但我想要的是字形的拉伸版本。

PS:实际上我需要用一个字形(Kashida)来填补空白,它看起来与水平线相同,MainScenario 会画一条线来代替,但这样一来,这条标尺/线与其他字形的连接处就会出现凹痕。我注意到拉伸的字形没有这个问题(可能是由于字体提示)。这就是为什么我想找到一种解决方案来像胶水一样拉伸字形。

谢谢

答案1

您需要在段落被分成几行之后测量拉伸宽度,而不是在插入 chardef 标记时测量。这意味着您需要运行两次 latex 才能使其工作。

在此处输入图片描述

\documentclass[10pt,a4paper]{article}
\usepackage{graphicx}

\makeatletter   %would do nothing inside `\newcommand`
\newcount\zzcount
% don't do new... allocations inside another macro
    \newXeTeXintercharclass \mycharclassA%
    \newXeTeXintercharclass \mycharclassB%
    \XeTeXcharclass `\A \mycharclassA
    \XeTeXcharclass `\B \mycharclassB   
    \chardef\mylinechar=`= %
    \def\mystretchedchar{%
    \leavevmode
    \global\advance\zzcount\@ne
     \pdfsavepos
     \edef\tmp{\write\@auxout{\gdef\expandafter\string\csname TESTA\romannumeral\zzcount\endcsname{\noexpand\the\pdflastxpos}}}%
     \tmp
     \hspace{0pt plus 5em}%
     \pdfsavepos
     \edef\tmp{\write\@auxout{\gdef\expandafter\string\csname TESTB\romannumeral\zzcount\endcsname{\noexpand\the\pdflastxpos}}}%
     \tmp
     \expandafter\ifx\csname TESTA\romannumeral\zzcount\endcsname\relax\else
     \llap{\resizebox{\dimexpr
\csname TESTA\romannumeral\zzcount\endcsname sp - 
\csname TESTB\romannumeral\zzcount\endcsname sp
\relax}{\height}{\mylinechar}}%
     \fi
    }
    \makeatother

\newcommand \stretchit{%%%%
    \XeTeXinterchartokenstate 1 %%% leave space after 1
    \XeTeXinterchartoks \mycharclassA \mycharclassB = {\mystretchedchar}%%%
}
\begin{document}
\stretchit{}
Test test test testABTest test test testTestTesttesttest testTest test test test test test test

zz Test test test testABTest test test testTestTesttesttest testTest test test test test test test zzzz zzzz 

zzzz Test test test testABTest test test testTestTesttesttest testTest test test test test test test zzzz zzzz zzzz zzzz zzzz zzzz 


\end{document}

相关内容