<Swing Dev> [9] Review request for 8132119 Provide public API for text related methods in SwingUtilities2

Phil Race philip.race at oracle.com
Wed Apr 27 23:03:01 UTC 2016


I referred  to this issue on this thread many emails ago as one reason 
why float might be better.

 >   But we have only API which gets a chars width and draws a text from 
int position in the user space.

There have been such APIs on the 2D classes since JDK 1.2, eg :

https://docs.oracle.com/javase/8/docs/api/java/awt/Graphics2D.html#drawString-java.lang.String-float-float-
https://docs.oracle.com/javase/8/docs/api/java/awt/Font.html#getStringBounds-java.lang.String-java.awt.font.FontRenderContext-

Swing should be able to use these - or one of the other related ones - 
where it needs floating point.

When Swing detects complex text it turns over editing and highlighting 
to TextLayout, does it not ?
Perhaps doing the same for hi-dpi would work as well.

-phil.

On 04/27/2016 01:41 PM, Alexandr Scherbatiy wrote:
>
>
>   I just want to highlight one more problem which happen even font 
> metrics with right transform are used.
>   It refers to the text selection.
>
>   Suppose there is a graphics with scale 2. The char 'a' advance can 
> be 13 in device space and 13 / 2 = 6.5 in user space.
>   The task is to highlight a selected text in the middle of a string
>
>   Let's the selected index will be 11. The x coordinate to draw the 
> selected text is FontMetrics.charsWidth(chars, 0, index) = 72.
>    The selected text drawn from this position will be shifted to the 
> right because real x coordinate in user space is 6.5 * 11 = 71.5.
>   This leads that text is jumping when it is selected and deselected.
>
>   To properly draw a selected text in this case there should be API 
> which allows both return float chars width and draw a text from float 
> position.
>   But we have only API which gets a chars width and draws a text from 
> int position in the user space.
>
>   Below is a code which illustrate the text selection issue.
>   The image shows two strings which are selected from index 10 and 11. 
> The second selection is shifted to the right:
> http://cr.openjdk.java.net/~alexsch/8142966/images/text-selection.png
>
>   ----------------------------
>         int imgWidth = 400;
>         int imgHeight = 150;
>
>         BufferedImage buffImage = new BufferedImage(imgWidth, imgHeight,
>                 BufferedImage.TYPE_INT_RGB);
>
>         Graphics2D g = buffImage.createGraphics();
>         g.setColor(Color.WHITE);
>         g.fillRect(0, 0, imgWidth, imgHeight);
>
>         int x = 10;
>         int y1 = 20;
>         int y2 = 40;
>
>         g.scale(2, 2);
>         String text = "aaaaaaaaaaaaaaaaaaaaaaaa";
>         g.setColor(Color.BLUE);
>         char[] chars = text.toCharArray();
>         g.drawChars(chars, 0, chars.length, x, y1);
>         g.drawChars(chars, 0, chars.length, x, y2);
>
>         int selIndex = 10;
>         int selNum = 6;
>
>         FontMetrics fm = g.getFontMetrics(g.getFont());
>         g.setColor(Color.RED);
>         g.drawChars(chars, selIndex, selNum, x + fm.charsWidth(chars, 
> 0, selIndex), y1);
>         selIndex++;
>         g.drawChars(chars, selIndex, selNum, x + fm.charsWidth(chars, 
> 0, selIndex), y2);
>
>         g.dispose();
>   ----------------------------
>
>
> On 4/27/2016 6:17 AM, Philip Race wrote:
>> Applications cannot change the device transform and expect the same 
>> user space
>> metrics unless they specify fractional metrics to be ON.
>>
>> In your example below you may already have a scaled graphics context
>> if you were printing (for example).
>>
>> If you want no change to the user space positions or [as also 
>> implied] shapes of the glyphs
>> as the transform changes then you are asking for text that will not look
>> right at other resolutions. Printed text will look poorly spaced.
>>
>> Changing what happens in the font system is not an option since it
>> will break many applications - even if it were the right thing to do 
>> - which it is not.
>>
>> -phil.
>>
>>
>> On 4/26/16, 4:49 PM, Sergey Bylokhov wrote:
>>> On 27.04.16 1:50, Phil Race wrote:
>>>> Glyphs are always rasterised in device space so it does mean device 
>>>> space.
>>>
>>> I don't argue with it, the question is how to round.
>>>
>>>> The identity transform therefore happens to always return a user space
>>>> advance is that is an integer, but it is not bound to be so under any
>>>> other transform.
>>>
>>> I am not sure that this is correct. The simple example:
>>>
>>> BufferedImage bi = new BufferedImage(width, height,TYPE_INT_ARGB);
>>> int length = g2d.getFontMetrics().stringWidth(TEXT);
>>> Graphics2D g2d = bi.createGraphics();
>>> g2d.scale(2, 2);
>>> length = g2d.getFontMetrics().stringWidth(TEXT);
>>>
>>> In what space will be the length? I assume that this is the user 
>>> space. Note that if in the second time we get 13 pixels we will 
>>> round it to 7 (but rendering will be done to 6.5 * 2 = 13). My 
>>> suggestion in the fix is to make this round on the lower level and 
>>> use the same values as stringWidth() and during rendering.
>>>
>>>>
>>>> -phil.
>>>>
>>>> On 04/26/2016 03:28 PM, Sergey Bylokhov wrote:
>>>>> On 27.04.16 0:34, Phil Race wrote:
>>>>>> Fractional metrics being "off" does not mean that *user space* 
>>>>>> advances
>>>>>> need to be integers,
>>>>>> it refers to *device* space advances. Of course if your API does not
>>>>>> support floats you have a
>>>>>> problem - particularly if - you are character advance adding in 
>>>>>> which
>>>>>> case it is better to ask the
>>>>>> font system for the overall advance of the text.
>>>>>> https://docs.oracle.com/javase/8/docs/api/java/awt/RenderingHints.html#KEY_FRACTIONALMETRICS 
>>>>>>
>>>>>>
>>>>>
>>>>> The documentation says that in case of "fm-off" the "simplified 
>>>>> system
>>>>> based on integer device positions is typically used" + "rounding
>>>>> advance widths for rasterized glyphs to integer distances", it does
>>>>> not say that the "integer distance" should be rounded to the nearest
>>>>> device/pixel. It says that "rounding operations as the high quality
>>>>> and very precise definition of the shape and metrics of the character
>>>>> glyphs must be matched to discrete device pixels" I guess we should
>>>>> confirm the specification because results of the fix will be 
>>>>> "discrete
>>>>> number of device pixels", isn't it?
>>>>>
>>>>
>>>
>>>
>




More information about the swing-dev mailing list