Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Poor rendering if OS (Windows) scales to 125% due to monitor resolution #311

Open
folkfreund opened this issue Oct 14, 2023 · 14 comments
Open

Comments

@folkfreund
Copy link

Thanks for this really great piece of software!

I am using ICEpdf on a Windows 10 machine. My PDFs are rendered perfectly, as long as the monitor scaling is set to 100%.
When I move the viewer window to my other monitor, which has scaling set to 125% (recommended), then the PDF seems to be scaled up and fonts get blurred. This happens regardless of the current scaling factor in the viewer.

Is there any way to avoid this?

@pcorless
Copy link
Owner

Thanks, always nice to get some feed back, even more so if its positive.

This is an interesting problem. It's not specific the the library but from my readings is more of a JDK issue. Could you try the following systems properties (https://news.kynosarges.org/2019/03/24/swing-high-dpi-properties/)?

-Dsun.java2d.uiScale.enabled=false
-Dsun.java2d.win.uiScaleX=1.25 -Dsun.java2d.win.uiScaleY=1.25

@folkfreund
Copy link
Author

Hi Patrick, thanks for your quick response.
sure I'll try these properties. But I do not think, this will resolve the problem. I can't see how these properties could do the job on my dual monitor setup, one 100%, the other 125%.
I see, that the paintComponent function is called when I move the window from one monitor to the other. The graphics2D context gives me different scaling values (1.0 and 1.25) on the different displays.

Also I found an interesting statement here: https://github.com/JFormDesigner/FlatLaf/blob/main/flatlaf-core/src/main/java/com/formdev/flatlaf/util/UIScale.java
(See the comment at the top of the class l. 48-55)

Maybe the PDF could be prepared with higher resolution if necessary and drawn with scale 1.0?

pcorless pushed a commit that referenced this issue Oct 16, 2023
…ainting the page buffer at higher scale factors.
@pcorless
Copy link
Owner

The UIScale class you posted does indeed have some very interesting information in it.

The Viewer RI AbstractPageViewComponent uses a BufferedImage to cache the latest render of the PDF content. There is a bunch of logic that copies cached content and tries to limit the size of clip when updating for scrolling and scaling. The buffer is then painted using java.awt.Graphics2D and will pick up on the JRE applied scaling. This probably explains the blurring you are seeing.

I don't have the hardware to test this properly any chance you could pull https://github.com/pcorless/icepdf/tree/GH-311.fraction.scaling.compensation and give the theory a try?

@folkfreund
Copy link
Author

Yes, sure I'll give this a try :-)
You don't need special hardware, you can always change the scaling of your display (as long as you are on windows).

@folkfreund
Copy link
Author

folkfreund commented Oct 16, 2023

It seems, your idea does not change anything. :-(

If you add
double scale = g2d.getTransform().getScaleX()
scale contains 1.25, even after scale was set to 1.0 as in your try. It seems, the call to scale just modifies the existing transformation.

I also tried to replace the AffineTransform with identity transform (I know, you should NEVER do that...). Then the PDF content is not scaled any more and thus look fine, but the 'paper' is too big. It seems, it was painted before already.

Maybe we could do something like

double scale = g2d.getTransform().getScaleX();
if (scale != 1.0) {
  g2d.scale(1.0/scale, 1.0/scale);
}

and something similar where the paper boundaries are painted?

@folkfreund
Copy link
Author

folkfreund commented Oct 16, 2023

I experimented a bit and now I'm able to prevent the scaling. The page layouts (e.g. OnePageViewLayout) do not consider the smaller scale of the pages yet (sure this can be fixed, too).

But I'm not sure if this is what we really want. Before I continue please let me know what you think:

What is the real meaning of a scale 100% shown by the UI? Should the page appear on the screen in the same size as printed on paper?
Then we are not allowed to just avoid the upscaling on a screen with smaller dots.

BTW: on my normal 100% screen a A4 page shows up with a width of 161mm (should be 210mm) It might be by coincidence, but the factor is almost 96 / 72. Could it be, that there should be an additional scaling from 72 pt/inch to 96 px/inch?

But maybe nobody cares about the real size of the picture on the screen?

@pcorless
Copy link
Owner

That's interesting about the page layouts but I guess that makes sense in a way. I'll give it another try and see about passing in the scale factor into the code that creates the buffer, see if I can make some headway with that angle. I haven't been able to reproduce this on my Linux system yet but will keep trying. Any chance you could post a screen shot of the blurred output?

Papers size has come up over the years but I could probably count then on one hand. It's pretty much just like you pointed out 72 pt/inch to 96 px/inch. The PDF spec states one thing and Java2D does another. I don't think this would be too difficult to fix but I think there are some consideration with Apple and Windows but I can't remember if Java2d automatically corrects for that. More reading.

@folkfreund
Copy link
Author

Here are some screenshots.
First blurred output on my 125% display, created with icepdf master
blurred_125
Then the same on my 100% display, window just moved to the other screen
perfect_100

And now my current state with my fixes. PDF looks fine, but the layout/background is too big. Note the vertical scrollbar and off center horizontally
fixed-bad-layout1
Last an example with TwoColumnPageViewLayout
fixed-bad-layout2

@folkfreund
Copy link
Author

Yes, maybe it is worth a try to directly create the image with a modified scaling factor. The bad thing is, that we cannot get the scaling factor before we get the Graphics2D in paint function...

Would you like me to create a pull request with my changes?
I'm not very familiar with GitHub. Do I need to do this from my repo at GitHub? Up to now I just cloned your repo locally.

@folkfreund
Copy link
Author

Another note:
up to now I just looked at the PDF content itself. No idea, if all the tools need scaling, too?

@pcorless
Copy link
Owner

I was poking around tonight and there really isn't much info on this issue. There is a thread on Intellij support that discusses the issue with regards to the the IDE. They seem to make the distinction of app scaling vs the jre scaling.

Have you tried a simple configuration of:
-Dsun.java2d.uiScale.enabled=true
-Dsun.java2d.uiScale=1
I'm curious what this produces vs.
-Dsun.java2d.uiScale.enabled=false

From you screen shots this definitely looks like the buffer being scaled by 1.25. In your cloned repo, you should be able to create new branch with your work committed to it. Then create a pull request against pcorless:master.

@folkfreund
Copy link
Author

-Dsun.java2d.uiScale.enabled=false does not work at all on 125% display, it just does not redraw the full window on resize
uiScale enabled=false

-Dsun.java2d.uiScale.enabled=true
-Dsun.java2d.uiScale=1
These turn off the scaling for the whole application. This avoids blurred display and might be used as workaround in some cases. But it is not, what I want for my app, where I'm integrating the viewer as a small part of the program.
fixed_scaling_1

I'll create the pull request later.

@pcorless
Copy link
Owner

pcorless commented Oct 19, 2023

Thanks for the info, I'll continue to work on the buffer angle. Found a pretty good lead here, https://stackoverflow.com/questions/61558678/how-do-i-double-buffer-in-java-swing-on-a-retina-display-without-losing-the-high . Fairly sure I can incorporate the approach.

@pcorless
Copy link
Owner

This is still on the top of my todo list. I'm currently trying to wrap up a bunch of work on redacting text.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants