如何获取要嵌入PDF的字体数据?

时间:2018-06-20 19:24:44

标签: c++ pdf winapi pdf-generation

我的MFC应用程序创建了PDF,现在我正在尝试嵌入字体,创建的PDF在Foxit,Chrome和Windows 8 PDF Reader中打开,但在Acrobat中却没有。

我尝试使用this online validator验证pdf文件,并显示

  

对象的标识6与对象的参考标识5不匹配。

     

无法读取嵌入式字体程序“ Candara”。


我认为嵌入的方式是正确的

3 0 obj
<</Type /Font
    /Subtype /TrueType
    /BaseFont /Candara
    /FirstChar 0
    /LastChar 255
    /Widths 4 0 R
    /FontDescriptor 5 0 R
>>
endobj

5 0 obj
<<
    /Type /FontDescriptor
    /FontName /Candara
    /Flags 32
    /FontBBox [-700 -500 1800 1500]
    /ItalicAngle 0
    /Ascent 12
    /Descent -4
    /CapHeight 8
    /StemV 109
    /FontFile2 6 0 R
>>
endobj

6 0 obj
<<
    /Length 100376
    /Length1 100376
>>
stream
    ... font bytes ...
endstream
endobj


我相信我的问题是通过

获得的字体数据
LONG ret = ::TTEmbedFont(pDC->GetSafeHdc(),
                    TTEMBED_TTCOMPRESSED, 
                    CHARSET_UNICODE,
                    &ulPrivStatus,
                    &ulStatus,
                    WriteEmbedProc,
                    lpvVecBytes,
                    nullptr,
                    0,
                    0,
                    nullptr);

我还尝试使用 TTEMBED_RAW TTEMBED_EMBEDEUDC



抱歉,冗长而含糊的解释,但我有点迷茫,

所以这是获取要嵌入的字体数据的正确方法吗?如果是,是否应该对字体文件对象应用过滤器?

编辑:我将应用程序更改为使用GetFontData,它返回字体文件的字节,并且根据我的研究,可以这样使用,但是我仍然不能在Acrobat中打开,在线验证站点仍然会显示相同的错误消息。

link到带有问题的PDF示例。

谢谢,我们将不胜感激!

1 个答案:

答案 0 :(得分:2)

嵌入的字体看起来不错。实际上,在获取字体对象时存在一个较低级别的错误。

尝试使用Xpdf查看PDF会导致交叉引用表xref num 5 not found but needed, try to reconstruct<0a>出错。

查看PDF末尾的交叉引用表:

xref 0 10 0000000000 65535 f 0000242485 00000 n 0000242426 00000 n 0000000016 00000 n 0000000155 00000 n 0000001081 00000 n % Wrong should be 0000241738 0000001081 00000 n
0000241929 00000 n 0000242056 00000 n 0000242353 00000 n

实际错误在交叉引用表的第6行上,其中包含对象6 0 R而不是5 0 R的字节偏移。

在线验证器The object's identity 6 doesn't match with the object's reference identity 5.发出的消息是由于在线验证器试图通过索引获取对象5 0 R而实际上获取对象6 0 R引起的。

此PDF的交叉参考表需要修复。