<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 11:31:40 UTC 2016
On 28.04.16 12:20, Sergey Bylokhov wrote:
> 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).
I suggest to implement it like on OSX, then tweak the algorithm of
rounding, and if after that someone will complains then add a new render
hint to round the text according the user space.
>
>>
>> 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