我想获取当前正在使用的字体的内部 PDF 对象编号。
pdfTeX 提供了需要字体名称作为参数的原语\pdffontobjnum
。我不知道字体名称应该是什么,例如类似cmr
?
无论我尝试什么,都会出现! Missing font identifier.
错误。
例如:
\documentclass{article}
\begin{document}
Test.
\pdffontobjnum\rmdefault
\end{document}
所以我的问题是,如何获取一个有效的字体名称作为参数传递给\pdffontobjnum
。
答案1
您可以使用\font
来获取当前字体:
\documentclass{article}
\begin{document}
Test.
\pdffontobjnum\font
\textit{\pdffontobjnum\font}
\end{document}
答案2
A字体标识符是与字体选择相对应的控制序列;它必须用原语来定义\font
(或\let
用如此定义的控制序列来定义)。
但是,有两个预定义的字体标识符。第一个是\nullfont
,由于没有字符,因此不是特别有用。第二个更有趣,它就是\font
它本身。
每当 TeX 寻找字体标识符时,如果找到,\font
它就会像使用与当前字体相对应的字体标识符一样执行操作。
在 LaTeX 中,字体标识符采用标准格式构建
\<encoding>/<family>/<series>/<shape>/<size>
例如,指的是默认字体。但是,这些标识符仅在发出命令并指向所需字体\OT1/cmr/m/n/10
时按需构建;因此\selectfont
\expandafter\pdffontobjnum\csname OT1/cmr/m/it/10\endcsname
Missing font identifier
如果文档中尚未选择字体,则可能会产生错误。因此,\pdffontobjnum
无论如何,在使用之前,您都需要选择字体。
仅按需构建标识符的问题并不是主要问题。考虑以下纯 TeX 示例:
\edef\tenitnumber{\pdffontobjnum\tenit}
\message{The font number is \tenitnumber}
\tenitnumber
\bye
这将导致低级致命错误:
This is pdfTeX, Version 3.14159265-2.6-1.40.18 (TeX Live 2017) (preloaded format=pdftex)
restricted \write18 enabled.
entering extended mode
(./alfon.tex{/usr/local/texlive/2017/texmf-var/fonts/map/pdftex/updmap/pdftex.m
ap} The font number is 1 [1]Assertion failed: (fo->last_char >= fo->first_char), function create_fontdictionary, file ../../../texk/web2c/pdftexdir/writefont.c, line 607.
)Abort trap: 6
因为内部数字指向一个显然没有创建的对象。如果你\it
在 之前添加\tenitnumber
,则不会出现错误,因此该字体实际上已在文档中使用。在框中使用字体是不够的:确实
\edef\tenitnumber{\pdffontobjnum\tenit}
\message{The font number is \tenitnumber}
\setbox0=\hbox{\tenit something}
\tenitnumber
\bye
也会以同样的方式失败。所以你必须在字体中排版某些内容,如果您想存储与其对应的对象编号。
LuaTeX 不会发生此错误;例如,
\edef\firstfont{\pdffeedback fontobjnum\tenit}
\firstfont
\bye
正确打印 1 并pdffonts
输出
name type emb sub uni object ID
------------------------------------ ----------------- --- --- --- ---------
SDXKYB+CMR10 Type 1 yes yes no 5 0