0

I am working on an app that has a Swing user interface. Text is being written to the window with a Graphics2D object (specifically SunGraphics2D) using the drawString method.

I have an issue where on high DPI displays some of the text renders very poorly, for example on a 4K monitor set to 150% scale.

The rendering can be improved by using -Dsun.java2d.uiScale=1.0, but this is simply disabling scaling, so everything is tiny.

If I had to guess what was happening, I would say that the graphics is being rendered at 1.0 scale, anti-aliasing is being applied, and then it is being scaled 1.5 times using Nearest Neighbour Interpolation. My reasoning for this is that it appears as though sometimes "anti-aliased pixels" (i.e. for black text, the light grey ones) are sampled for the scaling operation, which causes specific letters to be rendered unusually.

For example, this image shows the string "123" (I have enlarged it by 200% to make the issue more obvious):

Image of string "123" enlarged by 200%

As you can see the line that makes up the bottom of the "2" is 1px high, but the anti-aliasing is 2px high.

Another example with the string "555", where the base of the "5" is again very skinny:

Image of string "555" enlarged by 200%

Interestingly this doesn't affect all text, for example the text on JButton and JLabel objects renders at the correct scale and looks good:

A button with the text "Columns"

This issue does also affect images which are rendered within the window, but I am not very familiar with the image rendering classes of this particular application, so I cannot provide more info, other than to say this might point to the Graphics object being the issue.

I have tried to create a minimum example of the issue, but unfortunately when I create a brand new project the text renders perfectly, so it seems that this issue is specific to the application I am working on, which had many thousands of lines of code.

Is there something I should be looking into or trying? Perhaps there is a "Scaling Mode" for the graphics object, which is set to "Nearest Neighbour" or something like that?

I have tried to use a few RenderingHints such as RenderingHints.VALUE_FRACTIONALMETRICS_ON, but that didn't make any difference.

JDK is Eclipse Temurin 11.

Edit:

In case it is helpful, here are the RenderingHints being used: RenderingHints

Campbell
  • 532
  • 3
  • 12
  • I don't think the problem is related to text rendering. You said yourself images are also affected. I think you have an issue with the scale/resolution, which causes it to believe it has a different resolution than what it has. – RealSkeptic Oct 19 '22 at 15:43
  • The issue is after the fact scaling. The solution, as you said, is to disable scaling and design Swing GUIs to use larger font sizes. – Gilbert Le Blanc Oct 19 '22 at 15:51
  • @GilbertLeBlanc is there any way to improve the scaling, or change where in the rendering pipeline scaling occurs (i.e. before AA vs after)? It's not really feasible to redesign the whole GUI as the application has a lot of windows. – Campbell Oct 19 '22 at 16:00
  • You shouldn't have to redesign the whole GUI. What happens if you go and change all of the Swing comp[onents to a 16 point font? – Gilbert Le Blanc Oct 19 '22 at 21:13
  • Yesterday, I posted an example on how to create a component without the HiDPI zoom: https://stackoverflow.com/questions/74112645/jcomponent-for-images-with-no-zoom-for-hidpi . Maybe this can help you. – Anthony Oct 19 '22 at 22:16

0 Answers0