[OpenJDK 2D-Dev] [9] Review request for 8142966 Wrong cursor position in text components on HiDPI display
Sergey Bylokhov
Sergey.Bylokhov at oracle.com
Tue Feb 9 14:47:59 UTC 2016
Some additional information.
The Swing calculates the size of the components and location of the
cursor based on the text metrics. And these text metrics based on
advance. The Swing do not know to what destination it will be painted,
it calculates the size based on the non-scaled(non-retina) destination.
The problem occurs when we paint such component to the hidpi screen,
because we get small round errors per glyph -> this causes a visible
issueы when the text string is long. As a solution on the macosx the
round operation was done in the users space instead of dev space.
For example before the fix the size 1.4px was rounded to 3 (1.4 * 2 =
2.8 -> 3), but after the fix it will be 2 (1.4-> 1 * 2 = 2). So the
Swing will be able to calculate correct size/location without
information of the device scale. Note that the 3px(in dev space) is a
kind of fractional coordinate in the user space(1.5). And the Swing does
not work properly when fractional metrics are used, because it use ints
as a coordinates.
Note that the fix should be applied only when fractional metrics is off,
otherwise we should not use any rounding. I am not sure that the current
fix take it into account.
On 08.02.16 22:14, Jim Graham wrote:
> Isn't the problem there that we are returning an integer as the advance?
> Why aren't we returning 7.35 as a value instead of 8?
>
> Also, shouldn't 7.35 round to 7 and 14.7 round to 15?
>
> ...jim
>
> On 2/6/2016 7:28 AM, Alexander Scherbatiy wrote:
>> On 05/02/16 23:39, Phil Race wrote:
>>> Two things strike me when I read this
>>>
>>> 1) Initial surprise at how deep into the font code it goes.
>>> Perhaps there are alternatives.
>>>
>>> 2) That it changes to using the linear metrics for measuring advance.
>>> Regardless of (1) I do not think (2) is correct. I am fairly sure this
>>> will lead to changes in text advance. It seems like it must throw
>>> away adjusted metrics as a result of glyph hinting.
>>>
>>> I don't know what the fix should be, since I have not looked at the
>>> problem top-down, I am just seeing the bottom-up proposed solution.
>>> So all I can say for now is that it needs to be at least somewhat
>>> different.
>>
>> There was the same issue on Mac OS X which has been fixed in the
>> similar way:
>> 8013569 [macosx] JLabel preferred size incorrect on retina displays
>> with non-default font size
>> https://bugs.openjdk.java.net/browse/JDK-8013569
>> http://cr.openjdk.java.net/~serb/7190349/webrev.04/
>>
>> The problem is that in many case for UI scale 2 we return to a user
>> an unscaled value.
>> But a value for transformed glyph advance, rounded and descaled can
>> differ from just rounded glyph advance.
>>
>> For example, font[dialog, plain, 12] char 'a':
>> transform: 12, advance: 7.35, rounded advance: 8
>> transform: 24, advance: 14.70 round advance: 14
>>
>> and 8 does not equal 14 / 2.
>>
>> The solution for Mac OS X was to get the glyph advance using only
>> font transform, round it and then apply the dev transform:
>>
>> CGGlyphImages.m:
>> 481 advance = CGSizeApplyAffineTransform(advance, strike->fFontTx);
>> 482 if (!JRSFontStyleUsesFractionalMetrics(strike->fStyle)) {
>> 483 advance.width = round(advance.width);
>> 484 advance.height = round(advance.height);
>> 485 }
>> 486 advance = CGSizeApplyAffineTransform(advance, strike->fDevTx);
>>
>> Thanks,
>> Alexandr.
>>>
>>> -phil.
>>>
>>> On 01/27/2016 01:26 PM, Alexander Scherbatiy wrote:
>>>>
>>>> Hello,
>>>>
>>>> Could you review the fix:
>>>> bug: https://bugs.openjdk.java.net/browse/JDK-8142966
>>>> webrev: http://cr.openjdk.java.net/~alexsch/8142966/webev.00/
>>>>
>>>> The proposed fix rounds a glyph advance first and then scales it if
>>>> UI scales do not equal to one.
>>>>
>>>> Thanks,
>>>> Alexandr.
>>>>
>>>
>>
--
Best regards, Sergey.
More information about the 2d-dev
mailing list