RFR: 8319844 : Text/TextFlow.hitTest() is incorrect in RTL orientation [v14]

Karthik P K kpk at openjdk.org
Wed Feb 28 12:18:08 UTC 2024


On Tue, 27 Feb 2024 16:18:31 GMT, John Hendrikx <jhendrikx at openjdk.org> wrote:

>> Karthik P K has updated the pull request incrementally with one additional commit since the last revision:
>> 
>>   Fix repeating text node issue
>
> So, I looked into the mirroring problem as well.  I had to remove a single line from the original `getHitInfo` code to get it to work correctly.  Here's the image that shows the positions are all correct:
> 
> ![image](https://github.com/openjdk/jfx/assets/995917/2946a339-c2cd-4dcd-9ae7-95b212eb7bb8)
> 
> Here's the `getHitInfo` I'm using:
> 
> 
>     @Override
>     public Hit getHitInfo(float x, float y, String text, int textRunStart, int curRunStart) {
>         int charIndex = -1;
>         int insertionIndex = -1;
>         boolean leading = false;
> 
>         ensureLayout();
>         int lineIndex = getLineIndex(y);
>         if (lineIndex >= getLineCount()) {
>             charIndex = getCharCount();
>             insertionIndex = charIndex + 1;
>         } else {
>             if (isMirrored()) {
> //                x = getMirroringWidth() - x;
>             }
>             TextLine line = lines[lineIndex];
>             TextRun[] runs = line.getRuns();
>             RectBounds bounds = line.getBounds();
>             TextRun run = null;
>             x -= bounds.getMinX();
>             //TODO binary search
>             for (int i = 0; i < runs.length; i++) {
>                 run = runs[i];
>                 if (x < run.getWidth()) break;
>                 if (i + 1 < runs.length) {
>                     if (runs[i + 1].isLinebreak()) break;
>                     x -= run.getWidth();
>                 }
>             }
>             if (run != null) {
>                 int[] trailing = new int[1];
>                 charIndex = run.getStart() + run.getOffsetAtX(x, trailing);
>                 leading = (trailing[0] == 0);
> 
>                 insertionIndex = charIndex;
>                 if (getText() != null && insertionIndex < getText().length) {
>                     if (!leading) {
>                         BreakIterator charIterator = BreakIterator.getCharacterInstance();
>                         charIterator.setText(new String(getText()));
>                         int next = charIterator.following(insertionIndex);
>                         if (next == BreakIterator.DONE) {
>                             insertionIndex += 1;
>                         } else {
>                             insertionIndex = next;
>                         }
>                     }
>                 } else if (!leading) {
>                     insertionIndex += 1;
>                 }
>             } else {
>                 //empty line, set to line break leading
>                 charIndex = line.getStart();
>                 leading = true;
>                 insertionIndex ...

The simplified solution works for all the cases. Thanks @hjohn for suggesting this code change. 
I have simplified the function and removed extra parameters. I had to make same correction for insertion index similar to character index in Text class after getting hit info.
@andy-goryachev-oracle and @hjohn  please re-review the changes.

-------------

PR Comment: https://git.openjdk.org/jfx/pull/1323#issuecomment-1968857485


More information about the openjfx-dev mailing list