PDF文档文本在IE/Firefox/Chrome中的显示方式不同

use*_*741 3 pdf firefox pdf-generation google-chrome

我尝试用希伯来文本生成PDF文本文件.

我设法生成一个简单的文件.文件在这里

该文件在Adobe Acrobat Reader中完美打开,显示字符串"אאאווותתת".它在IE中也完美打开.

问题是其他观众表现得很糟糕:Google Chrome/Google Docs显示它没有出现所有"ו"(即三个字母"ו"消失!)

Mozilla Firefox显示它非常糟糕,在页面上多次显示一些字母和奇怪的位置...

我究竟做错了什么??文件有什么问题?

此处提供了该文件的链接

我知道这是一个棘手的问题.

任何帮助将不胜感激...

use*_*289 17

简短而简洁的介绍

PDF中的字体是PDF对象 - Font包含众多参数和子字典的字典,用于选择字形,显示它们并将字符代码转换为逻辑(Unicode)表示以进行内容提取.外行术语中的字体 - 我们将其视为*.ttf或*.pfb文件 - 被称为嵌入式或外部的字体程序,并由Font对象的子字典之一引用.

Fonts 分为两组:

  • 简单字体(Type1,Type3或TrueType),其中字形由单字节字符代码选择,该字符代码从文本显示运算符显示的字符串中获取.从代码到字形的映射称为字体编码,它可以内置到字体程序中,也可以由Font对象定义(通过预定义的名称或显式),或者在特殊情况下,根据查看器应用程序定义的规则构造.

有问题的文件不包含简单的字体,我们不会再进一步​​讨论它们了 - 但是,请注意,过于简单的描述甚至不会开始反映任何现实生活中的复杂性.

  • 复合字体(Type0),用于显示字符代码可以具有可变长度(最多4个字节)的文本,因此不限于256个代码点.键入0字体总是有一个后代这是一个字体状物体叫做CIDFont,而且,类似编码简单的字体,一个CMap对象,该字符代码映射到人物选择,其中,在PDF,总是CIDs-整数高达65536.

现在,字符选择器(CID)通常不直接用于从字体程序中选择字形.对于CIDFontCIDFontType2类型,它的字典中包含CIDToGIDMap的条目,即,很明显,映射CID到字型标识符.那些GIDs被,最后,用于选择从嵌入字形字体程序(对于CIDFontType2字体,是一个的TrueType字体程序(不混淆Font的对象的TrueType 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 
Run Code Online (Sandbox Code Playgroud)

当然没有'团体',他们在这里是因为我制作它们,基于CMap它包含2个范围:

<20> <20>
<0000> <19FF>
Run Code Online (Sandbox Code Playgroud)

总而言之,如果我们查找字符代码CMap并获取CID,然后查找CID CIDToGIDMap并获取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
Run Code Online (Sandbox Code Playgroud)

现在我们有足够的信息来推测,什么混淆了查看器应用程序


在我的第一次尝试中,我建议使用它32代码(和CID)用于非空格字符(请参阅上面的注释).这个假设是基于一个案例,几年前,当(旧版本)Acrobat没有显示带0x20代码的字符时,当它位于字符串的末尾时 - 假设它space实际上是根据编码向量(简单的字体),它是另一个角色.

我改变了这个:

  • 0x00200x0004在内容流;
  • 字节08和09输入CIDToGIDMap到GID = 159;
  • WidthsCID = 4到'vav'宽度的数组中的值;
  • ToUnicode cmap 相应调整.
  • (+后来我试图删除<0020> 32字符串CMAP- 未反映在文件中,在评论中链接)

嗯,它确实有所帮助,但不幸的是,一些观众仍然拒绝遵守规范.


然后我想,可能是变量字符代码宽度问题.

我回到原始文件并更改了:

  • 0x200x00e4在内容流;
  • <20> 228<00e4> 228CMAP;
  • codespacerange <20> <20>CMAP删除;
  • codespacerange <20> <20>ToUnicode Cmap删除.

文件似乎在所有观看者中完全打开,在下面的原始问题和评论中提到.奇迹般地,0x0020代码并且32 CID不干涉.


我认为,结论可能是这样的:

鉴于当前的事态,建议PDF创建者在字体编码(CMAP)中混合使用单字节和双字节代码.