[OpenJDK 2D-Dev] [9] Review request for 8142966 Wrong cursor position in text components on HiDPI display
Alexander Scherbatiy
alexandr.scherbatiy at oracle.com
Wed Mar 9 12:43:05 UTC 2016
Hello,
Could you review the proposed fix?
Thanks,
Alexandr.
On 13/02/16 00:16, Alexander Scherbatiy wrote:
> On 09/02/16 18:56, Sergey Bylokhov wrote:
>> Also probably it will be possible to test this via the public api
>> only(using the mix of the graphics transform + font transform).
>>
>> On 09.02.16 17:47, Sergey Bylokhov wrote:
>>> 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.
> The proposed fix is applied only when the fractional metrics are off.
>>>
>>>
>>> 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?
> 7.35 is returned when fractional metrics are on.
>>>>
>>>> Also, shouldn't 7.35 round to 7 and 14.7 round to 15?
> This happens because when fractional metrics are on the glyph
> linearAdvance value is returned (for current case
> ftglyph->linearHoriAdvance = 7.35).
> But when fractional metrics are off the glyph advance is returned
> (ftglyph->advance.x = 8).
> This calculation is done by freetype library.
>
> Thanks,
> Alexandr.
>
>>>>
>>>> ...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.
>>>>>>>
>>>>>>
>>>>>
>>>
>>>
>>
>>
>
More information about the 2d-dev
mailing list