一个非常简短和简化的介绍
PDF 中的字体是PDF 对象-Font
字典,包含许多参数和子字典,是选择字形、显示它们并将字符代码转换为逻辑 (Unicode) 表示以进行内容提取所必需的。外行术语中的字体(我们将它们视为 *.ttf 或 *.pfb 文件)称为字体程序,可以是嵌入的或外部的,并且由对象的子字典之一引用Font
。
Fonts
分为两组:
- 简单字体(Type1、Type3 或 TrueType),其中字形由从文本显示运算符显示的字符串中获得的单字节字符代码选择。从代码到字形的映射称为字体的编码,它可以内置在字体程序中,也可以由
Font
对象定义(通过预定义的名称或显式),或者在特殊情况下,由查看器应用程序根据定义的规则构建。
有问题的文件不包含简单的字体,我们不会进一步讨论它们——但是,请注意,过于简单的描述甚至没有开始反映任何现实生活中的复杂性。
- 复合字体 (Type0),用于显示字符代码可以具有可变长度(最多 4 个字节)的文本,因此不限于 256 个代码点。Type0字体总是有一个后代,它是一个名为的类似字体的对象
CIDFont
,并且与简单字体的编码类似,它是一个CMap
将字符代码映射到字符选择器的对象,在 PDF 中,字符选择器总是CIDs
-- 最大为 65536 的整数。
现在,字符选择器 ( CID
) 通常不直接用于从字体程序中选择字形。对于类型,它CIDFont
的CIDFontType2
字典包含CIDToGIDMap
条目,很明显,它映射CID
到字形标识符。最后,这些GIDs
用于从嵌入式字体程序中选择字形(对于CIDFontType2
字体,它是一个TrueType字体程序(不要与TrueTypeFont
的对象混淆))。 Subtype
Font
对象可以有ToUnicode
资源,将 CID 映射到 Unicode 值以进行索引、搜索和提取。它被称为ToUnicode Cmap
(因为它遵循类似的语法),但不应与CMap
上面提到的对象混淆。
在我称之为简单的情况下(并且,我认为,明智的决定),CMap
是预定义的 Identity-H名称,CIDToGIDMap
是预定义的身份名称,因此,从字符串中提取的字符代码(显示运算符的文本参数)总是 2 -字节数字,有效地直接从嵌入式TrueType程序中选择字形。根据我的经验,这是最常见的情况,并且看起来就是这种情况,针对其测试通用软件。
但是,有问题的文件并非如此。
(简短的介绍结束)
在我们的文件中,显示操作符的文本有效地获取了这个字符串:
0x000a 0x000a 0x000a 0x20 0x0020 0x0020 0x0020 0x20 0x0025 0x0025 0x0025
当然没有“组”,它们在这里是因为我制作了它们,基于CMap
它包含 2 个范围:
<20> <20>
<0000> <19FF>
长话短说,如果我们查找字符代码CMap
并获取 CID,然后查找 CIDCIDToGIDMap
并获取 GID,然后查找嵌入的 David-Bold字体的 GID 并获取 Unicode 值,这是表格
Code CID GID Unicode Name
0x000a 10 180 05EA tav
0x0020 32 159 05D5 vav
0x0025 37 154 05D0 alef
0x20 228 03 0020 space
现在我们有足够的信息来推测,是什么让查看器应用程序感到困惑
在我的第一次尝试中,我建议它是用于非空格字符的32
代码(和)(参见上面的评论)。CID
这个假设是基于几年前的一个案例,当(旧版本的)Acrobat 没有用0x20
代码显示字符时,当它位于字符串的末尾时——假设它是space
,实际上,根据编码向量(一种简单的字体),它是另一个字符。
我改变了这个:
0x0020
在0x0004
内容流中;
- 字节 08 和 09
CIDToGIDMap
到 GID=159;
Widths
CID=4 到 'vav' 宽度的数组中的值;
ToUnicode cmap
进行了相应的调整。
- (+ 后来我尝试
<0020> 32
从 - 中删除字符串CMAP
- 未反映在文件中,在评论中链接)
嗯,它确实有帮助,但不幸的是,一些观众仍然拒绝遵守规范。
然后我想,也许可变字符代码宽度是问题所在。
我返回到原始文件并更改了这个:
0x20
在0x00e4
内容流中;
<20> 228
到; <00e4> 228
_CMAP
codespacerange
<20> <20>
CMAP
已删除;
codespacerange
<20> <20>
在ToUnicode Cmap
删除。
该文件似乎可以在所有查看器中完美打开,在下面的原始问题和评论中提到。奇迹般地,0x0020
编码并32
CID
不受干扰。
我认为,结论可能是这样的:
鉴于目前的情况,不建议 PDF 创建者在字体编码中混合单字节和双字节代码 ( CMAP
)。