<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