bell-sw / LibericaNIK

Native Image Kit
8 stars 0 forks source link

Ugly/Pixellated text on NIK-compiled AWT/Swing app, on Linux, in *some* WMs/DEs #8

Open apocalyptech opened 1 year ago

apocalyptech commented 1 year ago

Hello! I was testing out some NIK builds of an AWT/Swing app on Linux, and one issue I've been running across is that the font rendering on the compiled version is really choppy and ugly -- I assume it's a lack of antialiasing or the like. When I've run across this kind of font problem in Java in the past, I'd typically just launch with an environment var like FREETYPE_PROPERTIES="truetype:interpreter-version=35" and that would fix it up, but it seems that the compiled version doesn't seem to look for those.

When running with the JDK supplied by the Liberica NIK package, the fonts display fine, including while running the agent to generate the JSON JNI/reflection/etc config. I'm using Liberica NIK 23 JDK 17. As an example, here's how it looks when running via the JDK (non-compiled):

screenshot-2023-08-12-00_45_44

... and here's how it looks when run via the binary:

screenshot-2023-08-12-00_46_07

Thanks, let me know if I can supply any extra info!

AlexanderScherbatiy commented 1 year ago

Hello,

Thank you for the report.

  1. Is the issue reproduced on Ubuntu or it needs to have some special version of Linux to reproduce the issue?
  2. Is the font issue reproduced with the simple SwingSample app (below) which just shows a JLabel? If no, is it possible to provide a code to reproduce the issue?
  3. Is the issue reproduced with standard fonts (like logical Dialog) or only with some custom fonts?
  4. Was special RenderingHints used to draw the text?
  5. Was Liberica NIK 23 JDK 17 Core, Standard or Full used?
  6. Could you run the sample where the issue is reproduced with NIK jdk and -Dsun.java2d.uiScale=1 option: bellsoft-liberica-vm-core-openjdk17-23.0.1/bin/java -Dsun.java2d.uiScale=1 Sample? Is the font quality changes comparing to running the jdk without the sun.java2d.uiScale option?
  7. Was FREETYPE_PROPERTIES="truetype:interpreter-version=35" environment variable also set both for running agent to generate configuration jsons and for creating the native image?

SwingSample.java:

import javax.swing.*;
import java.awt.*;

public class SwingSample {
    public static void main(String[] args) throws Exception {
        SwingUtilities.invokeAndWait(() -> {

            JFrame frame = new JFrame("Hello World");

            JLabel label = new JLabel("Hello, Wordl!");
        Font font = label.getFont().deriveFont(32.0f);
        label.setFont(font);
        System.out.printf("JLabel font: %s%n", font);

            JPanel panel = new JPanel(new BorderLayout());
            panel.add(label, BorderLayout.CENTER);

            frame.add(panel);
            frame.setSize(400, 300);
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frame.setVisible(true);
        });
    }
}
apocalyptech commented 1 year ago

Hello! Thanks for the response, and apologies it's taken so long to get back. I needed to spin up an Ubuntu VM to properly answer your questions, and a bunch of life stuff got in the way. :)

Anyway, just a short summary: Doing this via Ubuntu, the fonts actually look great! So it's something to do with the other couple of systems that I've been trying this on (namely, an Arch box, and a SteamOS box (which is based on Arch)). Since I've got an Ubuntu VM to play around with now, my next task is clearly to try and pinpoint the relevant differences between the two and see what's what. So, thanks for prodding me in that direction!

As to the specific questions you asked:

1. Is the issue reproduced on Ubuntu or it needs to have some special version of Linux to reproduce the issue?

As mentioned above, it looks like fonts are actually nice and smooth on Ubuntu. I'll get back to you with some more findings once I've had a chance to try and pinpoint things further.

2. Is the font issue reproduced with the simple `SwingSample` app (below) which just shows a JLabel? If no, is it possible to provide a code to reproduce the issue?

Yep, on my Arch desktop, the simple SwingSample does reproduce the problem. Running via Liberica's JDK looks fine, but running the Liberica NIK-compiled version ends up with choppy text:

screenshot-2023-09-03-11_29_43

(I upped the font size a little bit more to make it more clear.) And, again, on Ubuntu it actually works fine, so it's clearly down to some difference between the two.

3. Is the issue reproduced with standard fonts (like logical Dialog) or only with some custom fonts?

Yep, I've been using just the default Dialog font.

4. Was special `RenderingHints` used to draw the text?

Nope, nothing fancy!

5. Was Liberica NIK 23 JDK 17 Core, Standard or Full used?

Core

6. Could you run the sample where the issue is reproduced with NIK jdk and `-Dsun.java2d.uiScale=1` option: `bellsoft-liberica-vm-core-openjdk17-23.0.1/bin/java -Dsun.java2d.uiScale=1 Sample`?  Is the font quality changes comparing to running the jdk without the `sun.java2d.uiScale` option?

So when running it w/ java (as opposed to the NIK-compiled version), the fonts always look just fine, including when running with bellsoft-liberica-vm-core-openjdk17-23.0.1/bin/java. Adding in -Dsun.java2d.uiScale=1 didn't noticeably change anything for me. I did try adding that definition when running the agent, and then recompiling, but that didn't seem to make any difference on the compiled version.

7. Was `FREETYPE_PROPERTIES="truetype:interpreter-version=35"` environment variable also set both for running agent to generate configuration jsons and for creating the native image?

Yep, I'd made sure to try setting that during both agent run and compilation (though I assume it would be essentially ignored during the compilation step).

So yeah, thanks again for the reply -- I'll let you know once I figure out what the difference is between Arch + Ubuntu. I'm using a pretty basic window manager on the Arch side, whereas I'm guessing Ubuntu defaults to something fancier; perhaps it could actually be WM/DE-related? Anyway, I can investigate that myself. Cheers!

apocalyptech commented 1 year ago

I suppose one further Ubuntu-vs-Arch observation: the rendering issue looks to be entirely runtime, FWIW. The Arch-compiled version (which looks bad on Arch), looks totally fine when I transfer it over to the Ubuntu VM and run there. Likewise, the Ubuntu-compiled verison (which looks great in Ubuntu) looks bad if I transfer it back to Arch and run there.

So, presumably there's nothing at all wrong with the actual NIK compilation. This may not even be a valid bug. :D

Edit: hah, sheesh, yeah. So I use icewm on the Arch side. If I install icewm in Ubuntu and log in using that, the font rendering gets bad on Ubuntu too. So: fonts look just fine when run via Gnome, but bad via icewm. Will continue to dig.

Edit edit: Okay, wanted to get a feel for what environments produced good text and which produced bad, so installed a bunch and ran some tests. Just for reference, here's the ones that I'd tested:

    gnome (ubuntu default): good
    enlightenment: good
    kde plasma: good
    mate: good
    xfce4: good

    afterstep: bad
    awesomewm: bad
    fluxbox: bad
    i3: bad
    icewm: bad
    jwm: bad
    openbox: bad
    windowmaker: bad
apocalyptech commented 1 year ago

Aha! Okay, so the culprit here (or at least, the thing that the NIK-compiled binaries are attempting to look at), is "Xsettings." Those heavier DEs clearly all set them up -- for instance, with Gnome running, you'll see a gsd-xsettings running, and you can query the settings it's providing on the console by running dump_xsettings. When running Gnome, among the other settings provided, you'll see these:

Xft/Antialias 1
Xft/DPI 98304
Xft/Hinting 1
Xft/HintStyle "hintslight"
Xft/RGBA "rgb"

That "antialias" one in particular is certainly one of the ones needed here! You can dump those into a ~/.xsettingsd file and run xsettingsd to get them provided on DEs/WMs which don't natively supply xsettings of their own, and fonts in NIK-compiled binaries start looking good in there as well!

So, that's at least a way to get better font rendering on a system that's looking pixellated. It'd be nice if NIK-compiled binaries wouldn't need to read xsettings to do so, though. Perhaps there's some way to just force antialiasing regardless?