I am sorry. The JTextComponent.viewToModel(Point) method returns the
closest location for the provided point. If the caret position is N.25
the distance to the right character is 0.25 and to the left one is
greater than 0.75. Even in for the worst case the distance to the right
character is less than 1 and to the left is greater than 1 (suppose a
character width is greater than 1). For the provided cases the caret
should always be placed in the proper closest location.
There is just a question could a user just compare the provided magic
caret position (which coordinates are rounded) with the result of
rectangle from the method JTextComponent.modelToView2(position) which
returns the floating point positions. So for the same position the
rounded point can be (N, y) and the rectangle can have bounds (N.25, y,
w, h). Comparing these results can lead that the magic caret point does
not belong to the provided rectangle but it is definitely that the x
coordinate of this rectangle is the closest one to this point.
By the way, I can merge the added JTextComponent.modelToView2D(int
pos)/viewToModel2D(Point2D pt) public methods with the fix for the
8156217 Selected text is shifted on HiDPI display
http://cr.openjdk.java.net/~alexsch/8156217/webrev.04/
Thanks,
Alexandr.
On 8/10/2016 5:22 PM, Alexandr Scherbatiy wrote:
Suppose there is a text area with two lines with the same text:
abcdefghij
abcdefghij
The char 'c' on the fist line has offset 2 and some coordinates (x1,
y1) where x1 can have a floating point values like 21.25.
The char 'c' on the second line has offset 13 and coordinates (x2, y2)
where x2 is equal to x1.
Setting the caret to the first 'c' character sets the magic caret
position to (round (x1), round (y1)) position.
Pressing the arrow down key calculates the new y position and uses
the x position from the magic caret position which is round(21.5) = 21.
Now the new offset can be calculated as textComponent.viewToModel(new
Point(21, newY)) which returns offset 12 for char 'b' on the second
line instead the offset 13 for char 'c'.
Thanks,
Alexandr.
On 8/9/2016 11:32 PM, Philip Race wrote:
But characters are of varying width. Being on the "20th" char on line N
may mean being on the "25th" on line N+1.
So I am claiming this is nothing new and we really do not need do
anything here.
-phil.
On 8/9/16, 1:06 PM, Alexandr Scherbatiy wrote:
On 8/9/2016 12:44 AM, Phil Race wrote:
I was not familiar with this "magic caret" but from reading it
seems like it has just one use/purpose.
In the event that someone has multi-line text that you can navigate
around with up/down arrow keys
and that text has lines of varying length, you want a "preferred"
horizontal position for the caret
to be remembered so the caret is placed at that position whenever
the line of text has a length
greater than the caret position. Is there anything more to it than
that ?
Obviously the caret needs to be placed correctly in the context of
the text, so the precise position,
even in an all-integer world, is not going to line up on every
single line, unless you have monospaced text.
ie the "pixel" position is going to get converted into a position
on the leading or trailing edge of some glyph
So I wonder, does adding float matter .. is the extra precision
valuable here ?
It may depend on the rounding of a point position.
Suppose there are two lines with the same text. The caret is on
the first line can have x position N.25. Pressing down the arrow key
can round it to the N and the caret can be set to a previous char on
the second line.
Thanks,
Alexandr.
-phil.
On 08/04/2016 05:44 AM, Alexandr Scherbatiy wrote:
Hello,
Could you review the fix:
bug: https://bugs.openjdk.java.net/browse/JDK-8163124
webrev: http://cr.openjdk.java.net/~alexsch/8163124/webrev.00
The text position can have floating point value on HiDPI
display. The Caret interface should be updated to allow use
floating point positions.
The fix adds the following public API with floating point
positions:
javax.swing.text.Caret.getMagicCaretPosition2D()
javax.swing.text.Caret.setMagicCaretPosition2D(Point2D p)
javax.swing.text.JTextComponent.modelToView2D(int pos)
javax.swing.text.JTextComponent.viewToModel2D(Point2D pt)
javax.swing.text.ParagraphView.getClosestPositionTo(int pos,
Position.Bias b, Shape a, int direction, Position.Bias[], int
rowIndex, float x)
The fix replaces
Caret.getMagicCaretPosition()/setMagicCaretPosition(Point p) to
Caret.getMagicCaretPosition2D()/setMagicCaretPosition2D(Point2D p)
in all places
except DefaultCaret because DefaultCaret extends Rectangle so
its coordinates always have int values.
I have filled a separated enhancement for this JDK-8163174 Add
DefaultCaret2D which supports floating point API
To make a custom caret use floating point API it is also
necessary that PlainView.modelToView() returns a rectangle with
floating point values. It can be done after the fix
JDK-8156217 Selected text is shifted on HiDPI display
which implements Utilities.getTabbedTextWidth(Segment s,
FontMetrics metrics, float x, TabExpander e, int startOffset) method.
I have filled a separated issue on it:
JDK-8163175 PlainView.modelToView() method should return
Rectangle2D
Thanks,
Alexandr.