Как узнать, какие символы могут быть отображены в PDF заданным шрифтом? - PullRequest
0 голосов
/ 15 сентября 2018

У меня проблема как в этом вопросе : Некоторые символы не могут быть показаны в шрифте, который я использую (Lato-Regular.ttf). Шрифт загружается через

document = new PDDocument();
baseFont = PDType0Font.load(document, stream);

В комментарии мне сказали, что шрифты типа 0 давно устарели, однако в Javadoc из PDTrueTypeFont#load написано

Простые шрифты поддерживают только 256 символов. Для поддержки Unicode используйте PDType0Font#load(PDDocument, File).

что я и сделал.


Проблема возникла с \u0090, который на самом деле является управляющим символом, поэтому, очевидно, нет смысла его отображать. Основной причиной была неправильная кодировка, используемая при импорте.

Кажется, шрифт содержит все символы, которые мне были нужны. Однако в шрифте могут отсутствовать некоторые правильные символы, поскольку входные данные являются произвольной строкой Unicode.

Замена неверных символов тривиальна, но мне нужно знать, какие символы допустимы. Сначала я думал, что смогу использовать

PDType0Font.hasGlyph(code);

но код - это какой-то внутренний PDF-код, то есть совершенно бесполезный, когда у вас есть строка и вы не знаете, как конвертировать. Существует защищенный метод encode, который «кодирует данную строку для использования в потоке содержимого PDF» (что бы это ни значило), и ничто другое не звучит как преобразование.

Есть ли лучший способ, чем это безобразие?

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

1 Ответ

0 голосов
/ 19 сентября 2018

Замена неверных символов тривиальна, но мне нужно знать, какие символы действительны.

Использовать Font.canDisplayUpto(text)

String content = "ĈĉĜĝĤĥĴĵŜŝŬŭ";
java.awt.Font font = java.awt.Font.createFont​(java.awt.TRUETYPE_FONT,
                                              inputStream);
int index = font.canDisplayUpTo​(content);
if (index != -1) {
    throw new IllegalStateException(
        String.format("Font does not contain U+%06X: %s",
             context.codePointAt(index),
             font.getFamily()));
}

Для загрузки возможны TRUETYPE_FONT и TYPE1_FONT.Возможно, Type0 не охвачен, но вы упомянули совместимость с True-Type.

...