RFR: JDK-8294427 - Check boxes and radio buttons have rendering issues on Windows in High DPI env [v13]
Sergey Bylokhov
serb at openjdk.org
Sat Jun 10 01:24:10 UTC 2023
On Thu, 8 Jun 2023 20:39:09 GMT, Rajat Mahajan <rmahajan at openjdk.org> wrote:
>>> So, we ask Windows for the component image based on a particular DPI , not some specific size. The basic premise here is that we expect Windows returning image that would match the DPI , and then we perform our calculations accordingly. In the case above (if Region.clipRound is used) that basic premise is not met (if w, h=19) due to us calculating a DPI value of 140 which is closer to 120 or 125% scaling while our scaling is acytually 150% and Windows returns us a smaller size of the component than expected. So we don't need to add extra code to rescale , I believe. If we provide windows with correctly calculated DPI value which my code change does it should work fine as Windows will give us image of the correct size.
>>
>>
>> =( I am still missing something.
>> This is the code we discussing:
>>
>> int w = (int) Math.floor(destWidth + 0.5);
>> int h = (int) Math.floor(destHeight + 0.5);
>>
>> It calculates the size of the image we would like to render, it does not calculate the DPI. So if our component is 100x100 in pixels we create the image of that [size](https://github.com/openjdk/jdk/blob/79a4ac791c826656b3e984fe54dc472c62efd028/src/java.desktop/share/classes/sun/swing/CachedPainter.java#L155) and put it into the cache. Later when want to render that image to the place where the component of size 100x100 is located we request it from the PainterMultiResolutionCachedImage.getResolutionVariant.
>>
>> After this patch we create the image of one size using ceil, then request the image using floor, and it is somehow affected by the fact that the WIndows may return something different than requested.
>
> The above code calls getImage() and passes width and height to it.
>
> This is the flow :
> getImage(){CachedPainter.java} -> paintToImage() {XPStyle.java} -> ThemeReader.paintBackground ()
>
> We calculate and set scale in getImage() with this:
>
> https://github.com/openjdk/jdk/blob/727836ea85394b8baacd19a834f2993f06084c44/src/java.desktop/share/classes/sun/swing/CachedPainter.java#L170-L175
>
> So, scale changes based on height and width of the image which we get from the
> code you mentioned above.
>
> This scale is then used in paintToImage() to calculate DPI at Line 711 of XPStyle.java:
>
> https://github.com/openjdk/jdk/blob/727836ea85394b8baacd19a834f2993f06084c44/src/java.desktop/windows/classes/com/sun/java/swing/plaf/windows/XPStyle.java#L709-L711
>
> This DPI is then used to get the part size from windows and it changes as I explained in the previous comment.
> https://github.com/openjdk/jdk/blob/727836ea85394b8baacd19a834f2993f06084c44/src/java.desktop/windows/classes/sun/awt/windows/ThemeReader.java#L164
II am not sure that is correct way to calculate the dpi based on the "adhoc" change of the image size. That will add the mismatch between the code where we create the image, and the code where we request the image. We probably should change them both, or calculate the dpi in some other way.
Also the fact that on the image above one component is rendered twice smaller that another make me think that we did not rescale the image if the Windows return the image of the different size(You probably can prove that by always returning the wrong size from the native and check how it will look on HiDPI screen)
-------------
PR Review Comment: https://git.openjdk.org/jdk/pull/13701#discussion_r1224959410
More information about the client-libs-dev
mailing list