<Swing Dev> [9] Review request for 8132119 Provide public API for text related methods in SwingUtilities2
Phil Race
philip.race at oracle.com
Tue Apr 26 18:31:55 UTC 2016
On 04/26/2016 11:26 AM, Alexandr Scherbatiy wrote:
> On 4/26/2016 8:38 PM, Phil Race wrote:
>> On 04/19/2016 01:08 AM, Alexandr Scherbatiy wrote:
>>> On 4/11/2016 4:29 PM, Philip Race wrote:
>>>>
>>>>
>>>> On 4/6/16, 1:23 PM, Alexander Scherbatiy wrote:
>>>>>
>>>>> Hello,
>>>>>
>>>>> Could you review the updated fix:
>>>>> http://cr.openjdk.java.net/~alexsch/8132119/webrev.09
>>>>>
>>>>> - TextUIDrawing interface and its default implementaion
>>>>> BasicTextUIDrawing class are added
>>>>> - font metrics argument description is updated
>>>>>
>>>>> On 31/03/16 23:23, Phil Race wrote:
>>>>>> Another webrev where you have to slip past 40_ files to get to
>>>>>> the two that really matter :-)
>>>>>> I would have put SwingUtilities2.java and TextUIDrawing.java as
>>>>>> the first files.
>>>>> Updated.
>>>>>>
>>>>>>
>>>>>> Some of what I have to say here is more along the lines of things
>>>>>> to think
>>>>>> about rather than things that are wrong .. but there are also
>>>>>> maybe some things
>>>>>> that need to be fixed.
>>>>>>
>>>>>> Is javax.swing.plaf really the right package for the new class ?
>>>>>> I suppose it is for the use by the UI classes so maybe its right.
>>>>>>
>>>>>> Should the methods be taking "double" instead of "int" for
>>>>>> location ?
>>>>>> This means the measurement APIs too.
>>>>>> None of the JDK 1.2 text APIs use ints. That is all 1.0 legacy.
>>>>>> So if Swing internally wants to use ints that is OK but maybe the
>>>>>> API
>>>>>> should be floating point (double).
>>>>> The provided methods use Graphics as argument which only has
>>>>> drawString(String, int, int) method.
>>>>> If it is possible it is better to add the methods with float
>>>>> arguments and Graphics2D later.
>>>>>
>>>>>> Would that help hi-dpi at all ?
>>>>> The hi-dpi support mostly does not require changes in Swing.
>>>>> What it does just scales graphics using default transform from
>>>>> graphics configuration.
>>>>
>>>> Yes, but in another bug you are dealing with a problem positioning
>>>> the caret because of (somewhat) similar issues where coordinates
>>>> have been
>>>> rounded to an integral. A floating point value allows you to say that
>>>> this is 25.5 in user-space, even it if is 51.0 in device space.
>>>
>>> It needs some more investigation.
>>>
>>> What I have now is Swing uses font metrics to calculate a string
>>> width (FontMetrics.charsWidth(...)) which sums up float char values.
>>> The difference between font metrics used by Swing and font
>>> metrics from graphics passed to paint method is that the fist has
>>> null frc.tx matrix and the second one has a matrix with scales 2 on
>>> HiDPI display.
>>> The returned char width by the font metrics with null transform
>>> has value 7 for char 'a' (linear advance is 6.67 and xAdvance is 7).
>>> The char width for the font metrics with scaled transform is 6.5
>>> for the same font and char. FileFontStrike requests glyph metrics
>>> and gets linear advance 13.35 (dev transform is taken into account)
>>> xAdvance 13 - and apply the reverse transform. The result is 13 /
>>> 2 = 6.5.
>>>
>>> And this bothers me because a result for applying the tx transform
>>> and inverting it is different than just use the identity transform.
>>> There are definitely problems with advance rounding but it seems
>>> they are placed out of the Swing area.
>>>
>>
>> I am not sure if you are implying a bug in the font code, but there
>> is none that I see
>> from the above.
>>
>> There are several distinct issues here
>> 1) You must specify the device transform, unless you are requesting
>> and using linear advances.
>> 2) Linear advance is not generally used by Swing since it implies
>> unhinted text
>> 3) Rounding of advances back to user space is OK in the case of
>> hinted advances and
>> identity transform - ie the traditional Swing case - but in the
>> case like that you describe
>> where the device pixel advance is 13 for a (2.0,2.0) device scale
>> then the translation
>> back to user space can't express that accurately if it only has
>> int to work with,
>>
>> If Swing is not using the same device transform in calculating the
>> advance as it is when
>> drawing then that is a bug . That was the point of the comment we
>> added below about
>> obtaining the correct FontMetrics .. our L&Fs should be doing that as
>> well as admonishing
>> others to do so.
>
> It is true that Swing uses FontRenderingContext which does not
> take the graphics configuration transform into account.
>
> However, there are use case which should be considered:
>
> Using graphics configuration transform in Swing
> FontRenderingContext leads that text component size will depend on the
> graphics device.
>
> Let's take an a frame which has some text components placed in one
> row. Moving a frame from a non-HiDPI display to HiDPI display can lead
> that the size of text components can be changed and they will be
> rearranged in two rows.
> The same can be applicable for printing. Printing a text component
> from HiDPI display can lead that text will be shorter or longer than
> component bounds on a page.
Indeed .. and there have been bugs on this where Swing text is clipped
when printed.
Sadly I don't believe the bug tail from that has been completely squashed.
>
> There is one more case. A text component before it is added to a
> frame does not know about device where it will be shown.
> So the following is possible:
> -----------------
> JTextField textField = new JTextField("ABC");
> int width1 = textField.getWidth(); // no graphics
> configuration is provided, frc Tx is identity
> frame.add(textField);
> int width2 = textField.getWidth(); // frc Tx is 2 on HiDPI
> display
> -----------------
> Now it is possible that width1 is not equal to width2.
Absolutely true. And it is something Swing needs to handle.
-phil.
>
> Thanks,
> Alexandr.
>
>>
>>
>>>>
>>>>>
>>>>>> I suppose it would add over-head since all the existing code uses
>>>>>> int
>>>>>> and we are no worse off and can add double methods later if we
>>>>>> want to.
>>>>>>
>>>>>>
>>>>>> Regarding FontMetrics we need to add a caution that is must be a
>>>>>> FontMetrics
>>>>>> *obtained from the correct font and graphics*.
>>>>> Updated.
>>>>>>
>>>>>>
>>>>>> i.e what about attributes on the font such as "tracking" ?
>>>>>> or on the graphics such as FRACTIONALMETRICS
>>>>>> It looks like Swing might already fail if that were used.
>>>>>>
>>>>>> Look at this code :-
>>>>>>
>>>>>> public static int stringWidth(JComponent c, FontMetrics fm,
>>>>>> String string){
>>>>>> if (string == null || string.equals("")) {
>>>>>> return 0;
>>>>>> }
>>>>>> boolean needsTextLayout = ((c != null) &&
>>>>>> (c.getClientProperty(TextAttribute.NUMERIC_SHAPING) != null));
>>>>>> if (needsTextLayout) {
>>>>>> synchronized(charsBufferLock) {
>>>>>> int length = syncCharsBuffer(string);
>>>>>> needsTextLayout = isComplexLayout(charsBuffer, 0,
>>>>>> length);
>>>>>> }
>>>>>> }
>>>>>> if (needsTextLayout) {
>>>>>> TextLayout layout = createTextLayout(c, string,
>>>>>> fm.getFont(),
>>>>>> fm.getFontRenderContext());
>>>>>> return (int) layout.getAdvance();
>>>>>> } else {
>>>>>> return fm.stringWidth(string);
>>>>>> }
>>>>>> }
>>>>>>
>>>>>> The only thing Swing is looking at is one TextAttribute and
>>>>>> whether we have complex text.
>>>>>> That is not enough. This is an existing implementation issue but
>>>>>> one we should fix here.
>>>>>> You need to examine all the methods for similar issues.
>>>>> I created an enhancement for this:
>>>>> JDK-8153662
>>>>> SwingUtilities2.drawString()/getStringWidth()/clipString() should
>>>>> use more text attributes
>>>>> https://bugs.openjdk.java.net/browse/JDK-8153662
>>>>
>>>> you mean bug ? I upgraded it to P3 because it matters a lot more now
>>>> with this public API
>>>
>>> I do not think that it is a bug because the main request was to
>>> have methods which draw strings in the same way as it is done by
>>> Swing L&Fs.
>>
>> It seems like a bug to me
>>
>>> This will allow to have custom UI component which mimic to the
>>> standard L&Fs.
>>>
>>> It is also can be considered from the following point of view: is
>>> the proposed request to use more text attributes more important for
>>> standard Swing L&F or for custom L&F.
>>> It seems is not the first case because Swing lives with the
>>> current implementation for the long time.
>>> For the second case we provide the public TextUIDrawing interface
>>> which a developer can override and use any text attributes that are
>>> necessary.
>>>
>> We aren't talking about a separate API to provide text attributes, we
>> are talking about the
>> ones that are part of the font and the implementation is not respecting.
>>
>> -phil.
>>
>
More information about the swing-dev
mailing list