PDFBox:提取的字体中没有 U+0050 的字形

PDFBox: No glyph for U+0050 in extracted font

我正在尝试在文档中创建新页面并向其中写入一些文本,同时使用文件中包含的字体。

字体提取自资源:

PDPage page = document.getPage(0);
PDResources res = page.getResources();

List<PDFont> fonts = new ArrayList<>();

for (COSName fontName : res.getFontNames()) {
     PDFont font = res.getFont(fontName);
     System.out.println(font);
     fonts.add(font);
}

后来用来写一些文字:

stream.beginText();
stream.setFont(fonts.get(0), 12);
stream.setTextMatrix(Matrix.getTranslateInstance(20, 50));
stream.showText("Protokol");
stream.endText();

showText 方法总是失败并出现错误

No glyph for U+0050 (P) in font QZHBRL+ArialMT

但是字形在那里,正如 FontForge 验证的那样:

还有方法hasGlyphreturns正确。

包含 PDF 的完整项目可在 github repository showing the issue

获得

在这里你实际上 运行 进入一个打开的 PDFBox TODO,你的 stream.showText 最终为每个字符调用 encode 底层 CID 字体,这里我们有:

public class PDCIDFontType2 extends PDCIDFont
{
    ...
    public byte[] encode(int unicode)
    {
        int cid = -1;
        if (isEmbedded)
        {
            ...
            // otherwise we require an explicit ToUnicode CMap
            if (cid == -1)
            {
                //TODO: invert the ToUnicode CMap?
                // see also PDFBOX-4233
                cid = 0;
            }
        }
        ...
        if (cid == 0)
        {
            throw new IllegalArgumentException(
                    String.format("No glyph for U+%04X (%c) in font %s", unicode, (char) unicode, getName()));
        }

        return encodeGlyphId(cid);
    }
    ...
}

(org.apache.pdfbox.pdmodel.font.PDCIDFontType2)

如果 PDFBox 无法确定从 Unicode 到字形代码的映射 (if (cid == -1)),JavaDoc 注释指出了另一种确定字形代码的方法,即 ToUnicode[ 的反向查找=26=]地图。如果实现了这一点,PDFBox 就可以确定字形 ID 并写入您的文本。

遗憾的是还没有实现。

这已在问题 PDFBOX-5103. This will be available in PDFBox 2.0.23 and until then, in a snapshot build 中修复。