[OpenJDK 2D-Dev] [9] Review request for 8142966 Wrong cursor position in text components on HiDPI display

Sergey Bylokhov Sergey.Bylokhov at oracle.com
Fri Mar 25 21:29:22 UTC 2016


On 25.03.16 21:35, Alexandr Scherbatiy wrote:
>
>     I generated difference for all fonts from local graphics environment
> with size 12 between jdk with and without the fix for "low-dpi" display.
>     Results are in file [1] with simple format:

It will be useful to check the difference when the FontMetrics are ON.

>    ------------------------
> Font: java.awt.Font[family=Aharoni,name=Aharoni Bold,style=plain,size=12]
> [upper text width: 305] [upper text width: 306]
> [long  text width: 553] [long  text width: 554]
> [char [A] = 8] [char [A] = 9]
>
> Font: java.awt.Font[family=Andalus,name=Andalus,style=plain,size=12]
> [lower text width: 222] [lower text width: 220]
> [upper text width: 279] [upper text width: 275]
> [long  text width: 501] [long  text width: 495]
> [char [t] = 4] [char [t] = 3]
> [char [B] = 7] [char [B] = 6]
> [char [J] = 4] [char [J] = 3]
> [char [R] = 7] [char [R] = 6]
>    ------------------------
>
>    Where lower text width is width of the text "the quick brown fox
> jumps over the lazy dog", upper text width is width of the same text
> with upper case and long text is sum of these both texts.
>
>    166 fonts out of 362 have difference.
>
>    Links [2] and [3] contains some images with difference between drawn
> text before and after the fix. The text on the top is text before the
> fix, the text on the bottom is text after the fix and text between them
> shows the difference by red color.
>
>    [1]
> http://cr.openjdk.java.net/~alexsch/8142966/font-size-diff/font-size-diff_00.txt
>
>    [2] http://cr.openjdk.java.net/~alexsch/8142966/diff-images.00/low-case
>    [3]
> http://cr.openjdk.java.net/~alexsch/8142966/diff-images.00/upper-case
>
>    Thanks,
>    Alexandr.
>>
>> -phil.
>>
>> On 03/09/2016 04:43 AM, Alexander Scherbatiy wrote:
>>>
>>> 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.
>>>>>>>>>>
>>>>>>>>>
>>>>>>>>
>>>>>>
>>>>>>
>>>>>
>>>>>
>>>>
>>>
>>
>


-- 
Best regards, Sergey.



More information about the 2d-dev mailing list