Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Bad character spacing (kerning) in JavaFX's font rendering (in Linux)

I've started developing an application in JavaFX and I've run in an issue, I could find very little helpful information about: The spacing of between characters in Linux is very uneven. I'm not talking about the width of different characters but of the spaces between the characters.

It's visible in normal text, but the following example illustrates the effect better than normal text. Take a look at the first row. The space between the first two characters is smaller than between the second and third. This also happens between the sixth and seventh character and several others:

Uneven spacing of characters

Swing does not have this problem and JavaFX doesn't have this problem in Windows or it is barely visible on that OS. Neither does it appear to be a major issue on Mac. For comparison, here is a sample output on a Mac Retina MacBook Pro, mid-2014, running OS X 10.12.6 and Java 9.0.4:

enter image description here

Does anyone know if this is a bug in JavaFX's font rendering engine? If so, is there a workaround?

I'm really starting to wonder if I should change the framework as in my opinion such bad font rendering is not acceptable.

There is another question regarding this issue but it hasn't been answered, yet: Why does JavaFX add extra spacing between letters when using the Text component and how do I fix it?

I have been able reproduce this issue on two different Linux machines running Manjaro and in a virtual machine running Debian with the following code:

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);
    }
}
like image 920
Customizer Avatar asked Mar 06 '18 16:03

Customizer


2 Answers

jewelsea advised me to put my question on the openjfx-dex mailing list. The guys over there could explain what's going on:

It is not a problem of JavaFX but a configuration issue on my Linux system. JavaFX needs subpixel rendering to position the glyphs correctly. I'm using Manjaro, which is a derivative of Archlinux. In Archlinux, subpixel rendering is disabled by default, which has to do with patents covered by Microsoft.

In my case the problem could be solved by installing the freetype2-ultimate5 package from AUR, although the in the wiki mentioned freetype2-cleartype package is probably the better choice. But the latter one currently doesn't compile on my system because of another issue.

like image 141
Customizer Avatar answered Sep 23 '22 20:09

Customizer


Adding -Dprism.lcdtext=false might help, at least on Linux it removes the painful off-colour sub-pixel antialiasing attempt by using grayscale instead which is much cleaner.

like image 30
0__ Avatar answered Sep 25 '22 20:09

0__