Неверный интервал между символами (кернинг) в рендеринге шрифтов JavaFX (в Linux)

Я начал разработку приложения на JavaFX и столкнулся с проблемой, в которой я мог найти очень мало полезной информации о: Интервал между символами в Linux очень неравномерен. Я говорю не о ширине разных символов, а о промежутках между символами.

Это видно в обычном тексте, но следующий пример иллюстрирует эффект лучше, чем обычный текст. Посмотрите на первый ряд. Расстояние между первыми двумя символами меньше, чем между вторым и третьим. Это также происходит между шестым и седьмым персонажем и несколькими другими:

Неравномерный интервал символов

У Swing нет этой проблемы, и у JavaFX нет этой проблемы в Windows, или она едва видна в этой ОС. Это также не является серьезной проблемой для Mac. Для сравнения, вот пример выходных данных для Mac Retina MacBook Pro, середина 2014 года, под управлением OS X 10.12.6 и Java 9.0.4:

Кто-нибудь знает, если это ошибка в движке рендеринга шрифтов JavaFX? Если так, есть ли обходной путь?

Я действительно начинаю задумываться, стоит ли менять каркас, так как, по моему мнению, такая плохая отрисовка шрифтов неприемлема.

Есть еще один вопрос, касающийся этой проблемы, но на него пока нет ответа: почему JavaFX добавляет дополнительный интервал между буквами при использовании компонента Text и как я могу это исправить?

Я смог воспроизвести эту проблему на двух разных машинах Linux, работающих под управлением Manjaro, и на виртуальной машине под управлением Debian со следующим кодом:

package de.localtoast.fonttest;

import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;

public class FontTest extends Application {

    @Override
    public void start(Stage primaryStage) {
        VBox root = new VBox();
        Label label1 = new Label("0000000000000000000000");
        Label label2 = new Label("OOOOOOOOOOOOOOOOOOOOOO");
        Label label3 = new Label("oooooooooooooooooooooo");

        root.getChildren().add(label1);
        root.getChildren().add(label2);
        root.getChildren().add(label3);

        Scene scene = new Scene(root, 300, 250);

        primaryStage.setTitle("Font Test");
        primaryStage.setScene(scene);
        primaryStage.show();
    }

    public static void main(String[] args) {
        launch(args);
    }
}

1 ответ

Решение

Jewelsea посоветовал мне поставить вопрос в список рассылки openjfx-dex. Ребята там могут объяснить, что происходит:

Это не проблема JavaFX, а проблема конфигурации в моей системе Linux. JavaFX нуждается в субпиксельном рендеринге, чтобы правильно расположить глифы. Я использую Manjaro, который является производным от Archlinux. В Archlinux субпиксельный рендеринг по умолчанию отключен, что связано с патентами, защищенными Microsoft.

В моем случае проблему можно решить, установив пакет freetype2-ultimate5 из AUR, хотя в вики, упомянутом, пакет freetype2-cleartype, вероятно, является лучшим выбором. Но последний в настоящее время не компилируется в моей системе из-за другой проблемы.

Добавление -Dprism.lcdtext=false может помочь, по крайней мере, в Linux он устраняет болезненную попытку сглаживания субпиксельных субпикселей, используя вместо этого оттенки серого, что намного чище.

Другие вопросы по тегам