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.

Reply via email to