On 4/6/20 10:21 am, Alexander Zuev wrote:
Hi Alexey,

   i moved method from the new class to the FileSystemView and it works, 
however when
i tried to use it in the JFileManager on Windows i found that JFileChooser only 
uses large
icons in Places tab and with my code icons there are significantly worse even 
on 200%
magnification. They are sharper but the way we scaling them down just makes 
them a
pixelated garbage. You can look at the compare yourself:

The old method "FileSystemView.getSystemIcon(File)" as well as 
ShellFolder.getIcon(boolean) also
uses MRI, and works fine. As far as I understand we should be able to replace 
the usage of
ShellFolder.getIcon(true) by the new method FileSystemView.getSystemIcon(File, 
32x32). Also we
should be able to re-implement FileSystemView.getSystemIcon(File) by the 
FileSystemView.getSystemIcon(File, 16x16).
And this should not cause any visual regressions, otherwise, we have some 
issues in the new method.


http://cr.openjdk.java.net/~kizune/8182043/compare/

Naming is obvious - *old* are the original rendering, *new* is the modified 
with multiresolution image,
number at the end - magnification percent. Yes, the old icons look pretty 
blurry, but are new ones look any better?
Unless we change the way we downscale images in icons any images with high 
details will turn into this i'm afraid.

It is not necessary to downscale the image which we fetch from the native, I 
guess the reason
is that we request the size 256x256 from the native and then downscale?

So i'm proposing making the new method available for user to request image of 
arbitrary size but i don't think using it in
JFileChooser is a good idea. Unless, of course, we create the true 
multi-resolution image with all the resolution variants
rendered by the system - but that is impossible at the moment (as Eiric pointed 
out before) due to the JDK-8212226
not fixed yet - we will have errors on resolution switch or on moving of the 
window between screens with different
magnification factors.

Then how the old getSystemIcon(File) and ShellFolder.getIcon(boolean) work?


/Alex

On 01-Apr-20 20:06, Alexey Ivanov wrote:
Hi Alexander,

On 31/03/2020 15:51, Alexander Zuev wrote:
Hi Alexey,

  please see my answers inline.

On 31-Mar-20 12:52, Alexey Ivanov wrote:
<SNIP>
 - Can we try to re-implement the places where the old method 
ShellFolder.getIcon(boolean)
   was used, and change it to use the new public API, just to confirm that our 
new code is a
   a good replacement of the old/private api. I guess we could get rid the 
boolean version.
It is outside of the initial scope of the request but yes - i can do it. Should 
i do it within this fix or
should i create a new bug and do it there?

I think we should update implementation of ShellFolder.getIcon(boolean) to use 
the new API. This way, we'll also test the new API.
That would be a little bit backwards - i mean we are making a new API that 
exposes the new method inside the ShellFolder class and now we want to use it 
in the method within the ShellFolder itself? I would
prefer to avoid such circular dependensies and match the implementation of 
ShellFolder.getIcon
to use same LOGIC as the new API so FileManager can enjoy the new icons.

Why not? Currently, we have API which returns either small or large icon, 16px 
and 32px correspondingly. The new API can also return icons of these sizes; in 
addition to that, it can provide icons of other sizes.

Well, I meant not ShellFolder which is an “abstract” “interface” but 
Win32ShellFolder2 implementation.

 - The current spec for SystemIcon.getSystemIcon() specify that the icon will 
store the
   "maximum quality icon" what does it meant?
It means that the maximum size of the icon allowed by the system will be used. 
Right now on
Windows (and this issue is Windows specific) the maximum icon size allowed is 
256x256 pixels.
That is the size we will request and store in the MultiResolutionImageIcon.

What if 256×256 icon is not available. Will it result in Windows up-scaling the 
largest icon for us to 256×256 which we will down-scale to the requested size?
Yes, actually - Windows does scale automatically icons of the different sizes 
to the size requested by
user if such icon does not exist in the file's resources section.

This is why requesting 256×256 icon, if it does not exist, may result in 
upscaling by Windows, then we'll downscale it. I don't think the result would 
look good. But there's no way of knowing if the icon of the requested size is 
already scaled or not.

As I read in your initial note, sizes below 24 are not down-scaled. However, I think we should also make the exception for 32×32 icons too: it's the standard icon size which is also somewhat optimised for this size.
Well, i did some experiments and it would look almost identical as if we 
request this icon from the system on
100% magnification but as soon as we start changing magnification it starts 
showing the atrifacts of the
upscaling (especially when scale factor is not multiple of 100% - like on 130% 
scaling it looks very bad).
Approach with asking system for 256x256 icon and allowing our UI to scale it to 
exact physical resolution
looks almost the same at 100% magnification and looks way better on anything 
else.
The size of 48×48 could also be an exception as many applications provide this 
icon size since Windows XP era.

In general we should use the closest match to the requested size. 
Unfortunately, Windows does not provide an easy-to-use API which can give you 
the list of sizes available in the icon. Having the list, we can dynamically 
request the closest match and cache it, and then up- or down-scale it. This 
would also work well in High DPI environments with multiple displays: a multi 
resolution image would have use the right icon size. For example, 16×16 icon at 
200% scale is 32×32, so 32×32 icon can be used avoiding scaling up the small 
icon; or 32×32 icon at 150% scale is 48×48, this icon size is is also often 
available directly.
The problem is that sometimes 16x16 icon looks DIFFERENT from the 32x32 icon, 
you can look for it here
http://cr.openjdk.java.net/~kizune/8182043/new.png
Notice that on the top panel the first icon (size 16 folsed icon) looks 
different.

Yes. Icon is essentially a multi resolution image. If you take a look at how 
Windows behaves in HiDPI environment, you'll see that at 200% scaling it 
displays 32×32 icon in File Explorer list view which uses 16×16 icon in 100% 
scaling. We should do the same. If the requested size is 16×16 but we're 
rendering at 200%, we should use 32×32 icon if it's available rather than 
scaling up the 16×16 icon.

It took a screenshot of Notepad.exe in File Explorer and in JFileChooser:

http://cr.openjdk.java.net/~aivanov/8182043/notepad-100.png
http://cr.openjdk.java.net/~aivanov/8182043/notepad-200.png

The top image in either image is from File Explorer, the bottom one is from 
JFileChooser. In either case, the icons are identical; yet the icons look 
differently in 100% and 200%. The icon in case of 200% is not scaled up from 
16×16 but rather the real 32×32 icon.

I don't quite understand how it's achieved now in JFileChooser. It could be 
Windows draws a larger icon in HiDPI environment.

And that's why i made exception for the small icons - they sometimes are 
especially crafted by the
application authors and if we add upscaling/downscaling the file manager (for 
example) will show
application icon differently in the same view on different displays due to the 
different magnification factor.
And scaling 256x256 icon for scaling factors such as 130% or 145% looks MUCH 
better than scaling closest
resolution icon to the exact size (yes, Windows 10 allows custom scaling 
factors to be applied). So i still
think that keeping the maximum quality icon and scaling it down is a prefered 
way for all icons 32px or more.

Okay as long as it looks good. However, I'm still for using the icon provided 
in the app resources if the requested size matches the available size, but I 
don't really know how to achieve it.




--
Best regards, Sergey.

Reply via email to