2011-08-21 269 views
2

呈现由PDFCreator 0.9.x生成的PDF文件。我注意到它在字符映射中包含一个错误。现在,PDF文件中的错误毫无疑问,Acrobat在渲染错误的PDF文件方面有奇效,因此很多PDF生成器都会创建不完全符合PDF标准的PDF文件。PDF字体映射错误

我trief创建一个小例子文件:http://test.continuit.nl/temp/Document.pdf

单页面呈现使用TJ命令单个字形(大写的A)(参见流5 0 OBJ)。选中的字体(7 0 obj)包含嵌入单个字形的字体。到现在为止还挺好。 char被char#1引用。鉴于字体的编码,它包含一个差异部分:[1/A]。因此char 1 - >字符/ A。现在在嵌入子集字体中有一个与字符65不匹配字形的cmap(例如大写字母A),字体的cmap部分确实按照PDF文件Font - > Encoding - > Differences array中的顺序定义字符。

它看起来像字符映射/编码是两次。只有来自PDFCreator 0.9.x的文件似乎受到影响。

我的问题是:这是正确的(或者我犯了一个错误,是PDF正确的),你会做什么来检测这种情况,以解决渲染问题。

注:我确实需要能够使这些PDF ..

解决方案

在ISO32000文件存在的话是象征性的TrueType字体(标志位3是在字体描述符)编码是不允许的,你应该忽略它,总是使用简单的1on1编码。总之,如果它是一种符号字体,我完全忽略了Encoding对象,这就解决了这个问题。

+0

你用什么渲染文件? – userx

+0

@userx:用Delphi编写的我自己的PDF渲染器。它将内存中的PDF呈现为GDI设备(通常是位图,但也可以是打印机或任何其他GDI设备上下文)。 –

回答

2

第一点是该文件在Acrobat中打开并正确呈现,因此几乎可以确定该文件是正确的。事实上,它可以在各种PDF使用者中正确打开并呈现,所以实际上它是正确的。

有问题的字体是TrueType字体,所以实际上是的,有两种'编码'。首先是PDF/PostScript编码。这将字符代码映射为字形名称。在你的情况下,它将字符代码1映射到字形名称/ A。

在PostScript字体中,我们将查找CharStrings字典中的名称/ A,这会给我们字符描述,然后我们将执行该字符。不过,Tru​​eType字体的情况有所不同。

您可以将1.7 PDF参考手册,它规定的430页上找到此说:

“TrueType字体程序的内置编码直接从字符代码映射通过内部数据的手段字形描述称为“cmap”的结构(不要与第5.6.4节“CMaps”中描述的CMap混淆)。“

我相信你的情况,你只需要直接在CMAP子表中使用字符代码(0x01)。这会给你一个36的GID。

+0

关于你的第一点:现在创建PDF渲染器一年后,我可以告诉你:Acrobat在支持渲染错误的PDF格式方面非常出色。大多数PDF对象中缺少键。特别是在字体处理中,你会看到这些问题 –

+0

我看到的是相同的减去最后一段:在内容是绘制字符0x01的突击队。给定字体编码这是Postscript字符/ A。 TT字体在POST部分中没有填充字段,我像使用TT字体(不是typ0)的任何其他PDF一样使用TT cmap,并且我需要在给出Acrobat转换表格格式名称为Unicode代码的情况下查找字符65。大多数PDF的工作是正确的,只有使用PDFCreator创建的onse(据我现在看到的)不需要这个。请注意,TT字体中的Mac和MS cmap都使用相同的映射。其他人确实需要PDF中的编码。 –

+0

请注意,在PDF 1.7标准的第431页上,它声明您应该首先使用Endoding Dictionary和Differences,然后如果存在(3,1)“cmap”子表(Microsoft Unicode),则首先映射到PS名称,然后转换为Unicode值,然后使用(3,1)子表。这正是渲染器不工作的方式,并产生错误的结果(在PDFCreateor 0.9.x文件的情况下)。 –