atarw / material-ui-swing

A modern, Material Design UI for Java Swing
MIT License
656 stars 87 forks source link

Font scaling fix for high resolution screen #99

Closed mikera closed 4 years ago

mikera commented 4 years ago

I was testing material-ui-swing on a high resolution (3840*2160) and the font sizing ruined the look and feel of the application - many of the fonts were too large. This was with a display scaling of 200%

This PR fixes the issue on my machine - issue seemed to be due to some code that was increasing the font size unnecessarily.

This was on Windows 10 Pro with Java 13.0.1

Hope this is a helpful fix!

vincenzopalazzo commented 4 years ago

Hi @mikera,

Thanks for your work, but before to merge your pull-request I quant ask some details, like:

I was testing material-ui-swing on a high resolution (3840*2160) and the font sizing ruined the look and feel of the application - many of the fonts were too large. This was with a display scaling of 200%

You have restored al old code inside the material-ui-swing, I fixed this bug because inside linux the font was painted wrong this code

fontSettings.put (TextAttribute.SIZE, 14f);
fontSettings.put(TextAttribute.KERNING, TextAttribute.KERNING_ON);

With your code, the version of linux looked like

Selection_044

With the actual font setting.

Selection_045

If you do zoom, you can see the outlines of the pixeled font.

If you publish some screen of your problem we can found a solution

This post explained the issue https://stackoverflow.com/a/26564924/10854225

mikera commented 4 years ago

Screenshot

Here's a screenshot of what I'm seeing - basically everything is too big (compare with the font in the title bar, for example)

mikera commented 4 years ago

Screenshot1

Here's what is looks like after the patch, which to me seems about the correct size.

mikera commented 4 years ago

The directory bin is used for the release of the test library, an example: If inside an issue will request a new feature, we can create a new Jar inside this directory for testing.

I think this directory is necessary.

OK, I'll change this back in the PR - I just found it a bit unusual to have build outputs checked in to Github?

vincenzopalazzo commented 4 years ago

Hi @mikera,

OK, I'll change this back in the PR - I just found it a bit unusual to have build outputs checked in to Github?

Yes, I agree with you, a good job could be to implement the github action and for each commit to generate the new jar, but at the moment I won't implement the github actions and I will remain a possibility to download the test version library, with this method is possible to get the old version in the history github.

Here's a screenshot of what I'm seeing - basically everything is too big (compare with the font in the title bar, for example)

I think my code contains a bug, we can try to join our solution and get a good solution for the next release of the next version of the library, that is material-ui-swing_1.1.1.

mikera commented 4 years ago

I did a few more experiments and I am pretty sure the issue is somehow related to the Windows 10 "display scaling" feature. I normally run at 200%, otherwise everything is too small to read.

If I switch to 100%, the material UI demo looks correct (just very small).

So I think the issue is that the 200% scaling is getting applied twice (once by Windows, and another time by the Toolkit.getDefaultToolkit().getScreenResolution() scale factor.

vincenzopalazzo commented 4 years ago

@mikera, we ca try to increase the multiplicative value from 11 to 12 or 13, so the GUI is bigger.

But this doesn't resolve the problem 200% and I'm degree with you the problem was Toolkit.getDefaultToolkit().getScreenResolution() I tried on linux and I don't have your effect.

I'm thinking about a solution, but I don't have anything good idea

What do you thing about?

mikera commented 4 years ago

Just tested and Toolkit.getDefaultToolkit().getScreenResolution() returns 192 on my machine: so yes I definitely think this is the problem, it is scaling the font up to size 29.3!

mikera commented 4 years ago

An alternative might be to use Math.max(Toolkit.getDefaultToolkit().getScreenResolution(),96) or something similar. That would fix my specific problem, not sure how it would behave for other use cases though...

vincenzopalazzo commented 4 years ago

Your alternative worked also on 1366 x 764, we can try this code inside the pre-release version material-6.2?

You have time to add this code inside your PR, and tomorrow I will push the last version of the code in this project? Do you like this idea?

mikera commented 4 years ago

Made some changes as proposed - hopefully this works for you too?

vincenzopalazzo commented 4 years ago

@mikera Yes worked, Tomorrow I will build the new version of the library called material-1.1.1-pre-release6.1 and after I will create the test with Reddit community. Thanks for your work in the library

mrserb commented 4 years ago

Small notes: I think you should not use Toolkit.getDefaultToolkit().getScreenResolution(), it returns the value for the primary monitor only. I guess you need to use getLocalGraphicsEnvironment() .getDefaultScreenDevice().getDefaultConfiguration().getDefaultTransform(). for the primary screen and for any other screen; getLocalGraphicsEnvironment() .getScreenDevices()[XXX].getDefaultConfiguration().getDefaultTransform();

This default transform can be used to map the coordinates in the "user's" coordinate space(used by the most Swing/AWT API) and the real device space(actual pixels). So if you use fontSize=11 and want to draw it to the HiDPI screen you need to apply this transform. But if the Frame will be moved to the lowDPI screen then you probably will need to reload the fonts.

BTW, for sure, it depends on how these fonts will be used, probably the current code is fine.

mrserb commented 4 years ago

BTW I suggest to test your application by setting different scales: java -Dsun.java2d.uiScale=2 -jar XXX - This will emulate the 200% scale of the Windows. And it will be even better to test fractional scales like 1.5 and 2.5.

vincenzopalazzo commented 4 years ago

HI @mrserb,

I'm happy to read this message and thank you for your time, I think after reading your message that the actual choice to use Toolkit.getDefaultToolkit().getScreenResolution() is wrong because the complex client application could exist problems with a monitors with different resolutions.

This is a problem for the moment but with this code fontSettings.put (TextAttribute.SIZE, 14f); the font was pixeled.

I'm thinking to change the approach and I'm thinking to remove the personal font to l&f because this has some problem like this and I didn't found a method to support the emoji.

You think that removes the personal font to L&f is a good choice?

some issue correlated to this choice

https://github.com/atarw/material-ui-swing/issues/93

https://github.com/vincenzopalazzo/material-ui-swing/issues/87

Thanks for your time.