Skip to content

Commit b5fe362

Browse files
author
Andy Goryachev
committed
8330590: TextInputControl: previous word fails with Bhojpuri characters
Reviewed-by: kpk, arapte
1 parent 9dc4aa2 commit b5fe362

File tree

2 files changed

+38
-3
lines changed

2 files changed

+38
-3
lines changed

modules/javafx.controls/src/main/java/javafx/scene/control/TextInputControl.java

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2011, 2023, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2011, 2024, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -810,8 +810,7 @@ private void previousWord(boolean select) {
810810
int pos = wordIterator.preceding(Utils.clamp(0, getCaretPosition(), textLength));
811811

812812
// Skip the non-word region, then move/select to the beginning of the word.
813-
while (pos != BreakIterator.DONE &&
814-
!Character.isLetterOrDigit(text.charAt(Utils.clamp(0, pos, textLength-1)))) {
813+
while (pos != BreakIterator.DONE && !isLetterOrDigit(text, pos)) {
815814
pos = wordIterator.preceding(Utils.clamp(0, pos, textLength));
816815
}
817816

@@ -1743,4 +1742,15 @@ public int getAnchor() {
17431742
}
17441743
}
17451744

1745+
private static boolean isLetterOrDigit(String text, int ix) {
1746+
if (ix < 0) {
1747+
// should not happen
1748+
return false;
1749+
} else if (ix >= text.length()) {
1750+
return false;
1751+
}
1752+
// ignore the case when 'c' is a high surrogate without the low surrogate
1753+
int c = Character.codePointAt(text, ix);
1754+
return Character.isLetterOrDigit(c);
1755+
}
17461756
}

modules/javafx.controls/src/test/java/test/javafx/scene/control/TextInputControlTest.java

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2145,4 +2145,29 @@ private void copy(String string) {
21452145
content.putString(string);
21462146
Clipboard.getSystemClipboard().setContent(content);
21472147
}
2148+
2149+
@Test
2150+
public void previousWord_Bhojpuri() {
2151+
// "Bhojpuri \ud804\udca6\ud804\udcb7\ud804\udc94\ud804\udca3\ud804\udcb3\ud804\udca9\ud804\udcb2 test"
2152+
textInput.setText("Bhojpuri 𑂦𑂷𑂔𑂣𑂳𑂩𑂲 test");
2153+
textInput.end();
2154+
verifyCaret(28);
2155+
textInput.previousWord(); // at the beginning of "test"
2156+
verifyCaret(24);
2157+
textInput.previousWord(); // at the beginning of "𑂦𑂷𑂔𑂣𑂳𑂩𑂲"
2158+
verifyCaret(9);
2159+
textInput.previousWord(); // at the beginning of "Bhojpuri"
2160+
verifyCaret(0);
2161+
}
2162+
2163+
private void verifyCaret(int index) {
2164+
verifyCaret(index, index, false);
2165+
}
2166+
2167+
private void verifyCaret(int caret, int anchor, boolean reverse) {
2168+
assertEquals(caret, textInput.getCaretPosition());
2169+
assertEquals(anchor, textInput.getAnchor());
2170+
IndexRange sel = reverse ? new IndexRange(caret, anchor) : new IndexRange(anchor, caret);
2171+
assertEquals(sel, textInput.getSelection());
2172+
}
21482173
}

0 commit comments

Comments
 (0)