Fix the auto-composer to support supplementary chars

Change-Id: I61ff218ae2ca4eb443a370e581b677755258670a
main
Jean Chalard 2012-02-03 16:05:48 +09:00
parent 8174373a0e
commit 9159b9953d
2 changed files with 41 additions and 15 deletions

View File

@ -90,11 +90,11 @@ public class WordComposer {
* @return the number of keystrokes * @return the number of keystrokes
*/ */
public final int size() { public final int size() {
return mTypedWord.length(); return mCodes.size();
} }
public final boolean isComposingWord() { public final boolean isComposingWord() {
return size() > 0; return mCodes.size() > 0;
} }
/** /**
@ -125,8 +125,8 @@ public class WordComposer {
* @param codes the array of unicode values * @param codes the array of unicode values
*/ */
public void add(int primaryCode, int[] codes, int x, int y) { public void add(int primaryCode, int[] codes, int x, int y) {
final int newIndex = size(); final int newIndex = mCodes.size();
mTypedWord.append((char) primaryCode); mTypedWord.appendCodePoint(primaryCode);
correctPrimaryJuxtapos(primaryCode, codes); correctPrimaryJuxtapos(primaryCode, codes);
mCodes.add(codes); mCodes.add(codes);
if (newIndex < BinaryDictionary.MAX_WORD_LENGTH) { if (newIndex < BinaryDictionary.MAX_WORD_LENGTH) {
@ -171,8 +171,8 @@ public class WordComposer {
final KeyDetector keyDetector) { final KeyDetector keyDetector) {
reset(); reset();
final int length = word.length(); final int length = word.length();
for (int i = 0; i < length; ++i) { for (int i = 0; i < length; i = Character.offsetByCodePoints(word, i, 1)) {
int codePoint = word.charAt(i); int codePoint = Character.codePointAt(word, i);
addKeyInfo(codePoint, keyboard, keyDetector); addKeyInfo(codePoint, keyboard, keyDetector);
} }
} }
@ -207,16 +207,25 @@ public class WordComposer {
* Delete the last keystroke as a result of hitting backspace. * Delete the last keystroke as a result of hitting backspace.
*/ */
public void deleteLast() { public void deleteLast() {
final int size = size(); final int size = mCodes.size();
if (size > 0) { if (size > 0) {
final int lastPos = size - 1; mCodes.remove(size - 1);
char lastChar = mTypedWord.charAt(lastPos); // Note: mTypedWord.length() and mCodes.length differ when there are surrogate pairs
mCodes.remove(lastPos); final int stringBuilderLength = mTypedWord.length();
// TODO: This crashes and catches fire if the code point doesn't fit a char if (stringBuilderLength < size) {
mTypedWord.deleteCharAt(lastPos); throw new RuntimeException(
"In WordComposer: mCodes and mTypedWords have non-matching lengths");
}
final int lastChar = mTypedWord.codePointBefore(stringBuilderLength);
if (Character.isSupplementaryCodePoint(lastChar)) {
mTypedWord.delete(stringBuilderLength - 2, stringBuilderLength);
} else {
mTypedWord.deleteCharAt(stringBuilderLength - 1);
}
if (Character.isUpperCase(lastChar)) mCapsCount--; if (Character.isUpperCase(lastChar)) mCapsCount--;
} }
if (size() == 0) { // We may have deleted the last one.
if (0 == mCodes.size()) {
mIsFirstCharCapitalized = false; mIsFirstCharCapitalized = false;
} }
if (mTrailingSingleQuotesCount > 0) { if (mTrailingSingleQuotesCount > 0) {

View File

@ -159,11 +159,26 @@ public class InputLogicTests extends ServiceTestCase<LatinIME> {
} }
public void testPickSuggestionThenBackspace() { public void testPickSuggestionThenBackspace() {
final String WORD_TO_TYPE = "tgis"; final String WORD_TO_TYPE = "this";
final String EXPECTED_RESULT = "this";
type(WORD_TO_TYPE); type(WORD_TO_TYPE);
mLatinIME.pickSuggestionManually(0, WORD_TO_TYPE); mLatinIME.pickSuggestionManually(0, WORD_TO_TYPE);
mLatinIME.onUpdateSelection(0, 0, WORD_TO_TYPE.length(), WORD_TO_TYPE.length(), -1, -1);
type(Keyboard.CODE_DELETE); type(Keyboard.CODE_DELETE);
assertEquals("press suggestion then backspace", WORD_TO_TYPE, assertEquals("press suggestion then backspace", EXPECTED_RESULT,
mTextView.getText().toString());
}
public void testPickTypedWordOverAutoCorrectionThenBackspace() {
final String WORD_TO_TYPE = "tgis";
final String EXPECTED_RESULT = "tgis";
type(WORD_TO_TYPE);
// Choose the typed word, which should be in position 1 (because position 0 should
// be occupied by the "this" auto-correction, as checked by testAutoCorrect())
mLatinIME.pickSuggestionManually(1, WORD_TO_TYPE);
mLatinIME.onUpdateSelection(0, 0, WORD_TO_TYPE.length(), WORD_TO_TYPE.length(), -1, -1);
type(Keyboard.CODE_DELETE);
assertEquals("pick typed word over auto-correction then backspace", EXPECTED_RESULT,
mTextView.getText().toString()); mTextView.getText().toString());
} }
@ -379,4 +394,6 @@ public class InputLogicTests extends ServiceTestCase<LatinIME> {
assertEquals("type word type dot then press the .com key", assertEquals("type word type dot then press the .com key",
EXPECTED_RESULT, mTextView.getText().toString()); EXPECTED_RESULT, mTextView.getText().toString());
} }
// TODO: Add some tests for non-BMP characters
} }