Неверный интервал между символами (кернинг) в рендеринге шрифтов 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 он устраняет болезненную попытку сглаживания субпиксельных субпикселей, используя вместо этого оттенки серого, что намного чище.