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

Sergey Bylokhov Sergey.Bylokhov at oracle.com
Thu Apr 28 09:20:52 UTC 2016


On 28.04.16 2:03, Phil Race wrote:
> I referred  to this issue on this thread many emails ago as one reason
> why float might be better.
>
> Swing should be able to use these - or one of the other related ones -
> where it needs floating point.

The problem below and a suggestion of using float has the similar 
symptoms to the situation when fm-on, when actual rendering and metrics 
in "int" are different. The suggestion of using float is correct, but 
why it should be used when fm-off? according to the spec all metrics in 
this case should be calculated as "int". I still think that all these 
problems are occurs because we incorrectly calculate "int" metrics when 
fm-off(actually from the users point of view fm-off mode is useless, 
because even if fm-off the application get fractional data instead of 
expected ints).

>
> 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?
>>>>>>
>>>>>
>>>>
>>>>
>>
>


-- 
Best regards, Sergey.



More information about the swing-dev mailing list