Глиф шрифта не отображается с помощью Graphics2D drawString, начиная с Java 7u13

У меня странная проблема при рисовании строк с некоторыми конкретными шрифтами истинного типа в 32-битной Java в Windows 10.

Начиная с Java 7u13, всякий раз, когда символ / глиф шрифта шире, чем в 4 раза больше его высоты, он вообще не отображается с использованием Graphics2D.drawString (например, глиф шириной 4001em с базовым размером шрифта 1000em):

public void paint(Graphics g) {
    Graphics2D g2 = (Graphics2D)g;
    g2.setFont(new Font("myFontWithWideGlyphForX", Font.PLAIN, 12));
    g2.drawString("XXXX", 10, 10);
}

Однако шрифт отображается правильно на JLabel, поэтому после некоторого исследования базового кода Swing я понял, что установка подсказки рендеринга KEY_TEXT_ANTIALIASING на VALUE_TEXT_ANTIALIAS_LCD_HRGB обеспечивает правильную визуализацию текста:

public void paint(Graphics g) {
    Graphics2D g2 = (Graphics2D)g;
    g2.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,
    RenderingHints.VALUE_TEXT_ANTIALIAS_LCD_HRGB);
    g2.setFont(new Font("myFontWithWideGlyphForX", Font.PLAIN, 12));
    g2.drawString("XXXX", 10, 10);
}

Кажется, что алгоритм рендеринга работает по-другому после установки субпиксельного atialiasig и правильно отображает шрифт.

Если я переключусь на Java 7u11 или более раннюю версию, текст будет отображаться без проблем и без установки VALUE_TEXT_ANTIALIAS_LCD_HRGB.

То же самое происходит с любым другим шрифтом с такими широкими глифами - например, этот случайный шрифт имеет такой широкий глиф для символа "J": http://www.fontspace.com/digital-magic/hdgems5 - он нормально обрабатывает с Java 7u11, но не отображает вообще с чем-либо новее.

Установка субпиксельного сглаживания VALUE_TEXT_ANTIALIAS_LCD_HRGB только для рендеринга шрифта кажется хакерской, уродливой и не всегда возможной (например, при использовании сторонних библиотек). Кто-нибудь знает, в чем причина того, что awt не отображает такие символы с 7u13? Такой шрифт просто не поддерживается? А может это ошибка?


person rince    schedule 27.06.2017    source источник
comment
В Java 8 все символы отображаются при рисовании вручную, но имеют немного разную ширину. Я предполагаю, что показатели и / или подсказки в шрифте не полностью соответствуют требованиям, хотя у меня недостаточно знаний о файлах шрифтов Truetype, чтобы сказать наверняка.   -  person VGR    schedule 27.06.2017
comment
На моем компьютере с Windows 10 jdk8u131 не отображает заглавный символ J в связанном шрифте hdgems5 или любом другом шрифте, который я нашел с такими широкими символами (с использованием Graphics2d drawString).   -  person rince    schedule 27.06.2017
comment
Ни JLabel, ни пользовательское рисование с набором подсказок рендеринга не отображают глиф J, когда я тестирую его в Java 1.8.0_131, хотя он учитывает ширину глифа. Я провожу этот тест в 64-разрядной версии Linux, хотя был бы удивлен, если бы это имело значение, учитывая, что весь код рендеринга написан на Java.   -  person VGR    schedule 27.06.2017
comment
Все еще полезная информация, у меня не было возможности протестировать это в Linux. Я просто сбит с толку, почему это работало на Java7u11 и ранее. Тот факт, что подсказка рендеринга у вас не работает, просто доказывает, что это решение может работать не во всех системах.   -  person rince    schedule 28.06.2017


Ответы (1)


Мне не удалось получить ответ по этой проблеме, но я нашел способ ее обойти.

Ни один из найденных мной шрифтов .ttf не отображал глифы шире, чем в 4 раза превышала высоту ограничивающего прямоугольника / глифа при использовании Java 7u13 или новее. Эта проблема сохранялась независимо от того, какой инструмент использовался для создания шрифта.

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

person rince    schedule 02.10.2017