bluescan / tacentview

An image and texture viewer for tga, png, apng, exr, dds, pvr, ktx, ktx2, astc, pkm, qoi, gif, hdr, jpg, tif, ico, webp, and bmp files. Uses Dear ImGui, OpenGL, and Tacent. Useful for game devs as it displays information like the presence of an alpha channel and querying specific pixels for their colour.
ISC License
329 stars 32 forks source link

HighDPI support? #131

Closed teadrinker closed 11 months ago

teadrinker commented 12 months ago

Hello! I just tried this out on a windows 10 laptop with a 4k screen, and it's very hard to read the text and everything is tiny. The windows 10 scaling setting is 200%, which the default for this laptop.

Is this a bug, or is there just no support? (I'm happy to test more on this machine if needed in the future)

Love the quick start-up time of this app btw!

bluescan commented 11 months ago

Hello! On the Preferences page take a look at "UI Size" and set it to Large. You can also use Shift + and Shift -.

I admit that even 'Large' is quite small, but give it a shot nonetheless.

teadrinker commented 11 months ago

Cool, yes slightly better! If the app would also take the windows scaling setting into account, three would be enough! However, without taking it into account I would need something larger to avoid eye strain!

For reference, here's the windows explorer with Tacentview behind: tacentview_23-09-04__02-45-34

bluescan commented 11 months ago

Thanks for the pic. Don't disagree ;) So the easy part would be reading the OS scaling factor. The hard part is testing every window at the new larger size -- whether a function of the scale-factor or the UISize setting, this would need to be done considering how the ImGui calls are being made -- in addition, the font is prerendered into a texture (for speed), so the font sizes are not 'dynamic' and need to be predetermined.

I think the easiest would be to leave this issue open and probably introduce a couple more sizes... it 'could' later take the UI scale into account, but that wouldn't be the lion's share of the work in any case.

teadrinker commented 11 months ago

I see, yeah, these things are tricky to implement! For DPI support, having font texture dynamically/lazily created/cached would probably be good since there is also the case with multi-monitor setups with different DPI, so the app might need to switch when the window is dragged between them...

Thanks anyway for creating this software and releasing as open source!

bluescan commented 11 months ago

You're welcome ;) I am planning to (eventually) get to this task... I've been doing some experiments... not sure the best approach yet. This comment is mostly for my own reference, so no need to respond unless you want to ;)

I was hoping to just have one higher resolution font texture and globally scale it down. If this could work it would allow reading the OS scale directly and applying it. The image below is not completely convincing though.

image

The worst case is keeping the really small UI size looking ok... 14 pt. The left is a magnified view of the font rendered at 14pt and scale 1.0 The right is a magnified view at a 28pt render at scale 0.5. The scale is an ImGui parameter (not quite sure what filtering is being done for the downscale). Unfortunately the right has a few problems. Will see if I can get better results at higher pt values.

bluescan commented 11 months ago
image

56pt (0.25 scale) left. 14pt right. Still not great. Think I'll stick with the sep renders for 8 distinct pt sizes (14 to 28 in steps of 2). On load only 1 (the current size) need be generated... only if UISize is modified will it need to add to the font atlas. Will need a dictionary to go from the current UISize [0,8) to the ImFont index, since they may be out of order.

bluescan commented 11 months ago

Progress on this is proceeding (slowly). The final point sizes are 14pt to 36.4pt. This range is divided into 8 steps. The last step at 36.4pt roughly corresponds to an OS scaling of 250% (max allowed by windows). The first step up after 14pt is equivalent to 100%.

At present some of the UI has been made to work with these extended UI size ranges. Specifically the main operation buttons at the bottom, the details pane, the menu bar, the bottom nav bar, and the slideshow progress indicator now all work. The committed code is still restricted to the bottom three sizes until all UI elements work with the full range -- there's a RESTRICT_UI_SIZES define in Config.h that can be commented out to test the current state.

teadrinker commented 11 months ago

Cool! I tried it out, already better! I understand the issue, a lot of values (like button widths) now need to have a multipliers for larger text not to be cut-off! (Build process was great btw, just works!)

bluescan commented 11 months ago

Super. Gotta give some credit to cmake for the build system -- it sure does deal with a lot of the ugly details! This HighDPI task is forcing a lot of code cleanup... the contact sheet and thumbnail view should work now. I've defaulted it to 'on' and will fix the remaining dialogs / initial positioning of modals b4 next release -- as well as getting it to read the OS scale... the easy part ;) Appreciate the feedback.

bluescan commented 11 months ago

In progress:

bluescan commented 11 months ago

The system now reads the OS scale. There is an 'auto' mode in the UI Size preferences dropdown. Outstanding issues:

bluescan commented 11 months ago

The last part is done. In ab913d6d2a7f96c105be99a7b755e1ef53d55295 "Font optimization. On startup we only create the font atlas with a single font-size. Only if the UISize is modified do we regenerate the atlas with the remaining font sizes. This speeds up load time and in most cases UISize is not going to be modified."

I'm going to close this issue. If there are issues with any of the dialogs not showing text correctly they can be logged as separate issues or we can re-open. I'm not currently aware of any. There may be issues with multiple monitors at different scales... but that can be addressed when I start looking at better multi-monitor support ;)