Java 如何忽略PDFBox 2.0.7使用的字体中缺少的字形

Java 如何忽略PDFBox 2.0.7使用的字体中缺少的字形,java,pdf,exception,fonts,pdfbox,Java,Pdf,Exception,Fonts,Pdfbox,我看到在调用PDFPageContentStream的showText(String)方法时引发“java.lang.IllegalArgumentException:No glyph for U+05D0 in font”(例如)异常 捕获异常并没有多大帮助,因为无法编写好的字符。检查输入字符串中的每一个字符也不重要,这将是性能杀手(每个PDF可能有数千页,数百万个字符)。我真正需要的是一种方法来防止任何缺少的glyph出现异常,并将其自动替换为其他glyph,或显示unicode值的动态创建

我看到在调用PDFPageContentStream的showText(String)方法时引发“java.lang.IllegalArgumentException:No glyph for U+05D0 in font”(例如)异常

捕获异常并没有多大帮助,因为无法编写好的字符。检查输入字符串中的每一个字符也不重要,这将是性能杀手(每个PDF可能有数千页,数百万个字符)。我真正需要的是一种方法来防止任何缺少的glyph出现异常,并将其自动替换为其他glyph,或显示unicode值的动态创建的glyph

我不想因为字体不支持特定的字形而停止生成PDF,我只想使用一些替换字符,然后继续

如何做到这一点?

这就是我所做的

private final char[] replacements = IntStream.range(0, 1<<16)
    .map(c -> canRender(font, c) ? c : "?")
    .collect(StringBuilder::new, StringBuilder::appendCodePoint,
             StringBuilder::append)
    .toString().toCharArray();

// This is extremely ugly!!!
private boolean canRender(PDType0Font font, int codepoint) {
    try {
        font.getStringWidth(new String(Character.toChars(codepoint)));
        return true;
    } catch (final Exception e) {
        return false;
    }
}

String sanitize(String input) {
    return input.codePoints()
            .map(c -> c<replacements.length ? replacements[c] : '?')
            .collect(StringBuilder::new, StringBuilder::appendCodePoint,
                     StringBuilder::append)
            .toString();

private final char[]replacements=IntStream.range(0,1 c)“捕获异常没有多大帮助,因为不会写入好的字符。检查输入字符串中的每个字符也是一个性能杀手”-如果您很少获得该异常,则可以组合这些方法:捕获异常,并在catch块中检查输入字符串,相应地替换,然后绘制(现在已修改)再说一次字符串。也就是说,如果你编程好,以良好的方式检查输入字符串中的每个字符,这将不是性能杀手。“我只需要一些替换字符”,因此这将导致名字中有不寻常字符的人(例如Miško Hevery)收到PDF,而他们的名字类似于“Mi?ko Hevery”。我怀疑您的客户可能会想要。mkl,谢谢您的建议。不幸的是,这还不够好。是否可以指定字体的层次结构?这样,我可以使用客户选择的拉丁/扩展拉丁字体和第二种已知字体作为缺少字形的后备。可能吗?我的解决方案是强制使用包含必要字形的字体。但是,这是一个糟糕的解决方案。我必须向PDFBox项目提交一个功能请求,要求他们支持使用主字体的字体链,除非缺少字形,否则在字体链中为缺少的字形选择一种替代字体;如果没有字体包含字形,则n文档中呈现了替代标志符号(可能包含unicode值)。在这种情况下引发异常不会促进高质量应用程序的开发。