diff --git a/java/src/com/android/inputmethod/keyboard/ProximityInfo.java b/java/src/com/android/inputmethod/keyboard/ProximityInfo.java index aa499ed24..5c1808613 100644 --- a/java/src/com/android/inputmethod/keyboard/ProximityInfo.java +++ b/java/src/com/android/inputmethod/keyboard/ProximityInfo.java @@ -79,10 +79,12 @@ public class ProximityInfo { final ProximityInfo spellCheckerProximityInfo = createDummyProximityInfo(); spellCheckerProximityInfo.mNativeProximityInfo = spellCheckerProximityInfo.setProximityInfoNative("", - SpellCheckerProximityInfo.ROW_SIZE, 480, 300, + SpellCheckerProximityInfo.ROW_SIZE, SpellCheckerProximityInfo.PROXIMITY_GRID_WIDTH, SpellCheckerProximityInfo.PROXIMITY_GRID_HEIGHT, - (480 / 10), proximity, 0, null, null, null, null, null, null, null, null); + SpellCheckerProximityInfo.PROXIMITY_GRID_WIDTH, + SpellCheckerProximityInfo.PROXIMITY_GRID_HEIGHT, + 1, proximity, 0, null, null, null, null, null, null, null, null); return spellCheckerProximityInfo; } diff --git a/java/src/com/android/inputmethod/latin/WordComposer.java b/java/src/com/android/inputmethod/latin/WordComposer.java index 9f23f174f..231211d31 100644 --- a/java/src/com/android/inputmethod/latin/WordComposer.java +++ b/java/src/com/android/inputmethod/latin/WordComposer.java @@ -127,12 +127,8 @@ public class WordComposer { final int[] codes; final int keyX; final int keyY; - if (x == KeyboardActionListener.SPELL_CHECKER_COORDINATE - || y == KeyboardActionListener.SPELL_CHECKER_COORDINATE) { - // only used for tests in InputLogicTests - addKeyForSpellChecker(primaryCode, AndroidSpellCheckerService.SCRIPT_LATIN); - return; - } else if (x == KeyboardActionListener.SUGGESTION_STRIP_COORDINATE + if (null == keyDetector + || x == KeyboardActionListener.SUGGESTION_STRIP_COORDINATE || y == KeyboardActionListener.SUGGESTION_STRIP_COORDINATE || x == KeyboardActionListener.NOT_A_TOUCH_COORDINATE || y == KeyboardActionListener.NOT_A_TOUCH_COORDINATE) { @@ -149,27 +145,6 @@ public class WordComposer { add(primaryCode, codes, keyX, keyY); } - // TODO: remove this function - public void addKeyForSpellChecker(int primaryCode, int script) { - final int[] proximities; - final int proximityIndex = - SpellCheckerProximityInfo.getIndexOfCodeForScript(primaryCode, script); - if (-1 == proximityIndex) { - proximities = new int[] { primaryCode }; - } else { - // TODO: an initial examination seems to reveal this is actually used - // read-only. It should be possible to compute the arrays statically once - // and skip doing a copy each time here. - proximities = Arrays.copyOfRange( - SpellCheckerProximityInfo.getProximityForScript(script), - proximityIndex, - proximityIndex + SpellCheckerProximityInfo.ROW_SIZE); - } - add(primaryCode, proximities, - KeyboardActionListener.NOT_A_TOUCH_COORDINATE, - KeyboardActionListener.NOT_A_TOUCH_COORDINATE); - } - /** * Add a new keystroke, with codes[0] containing the pressed key's unicode and the rest of * the array containing unicode for adjacent keys, sorted by reducing probability/proximity. diff --git a/java/src/com/android/inputmethod/latin/spellcheck/AndroidSpellCheckerService.java b/java/src/com/android/inputmethod/latin/spellcheck/AndroidSpellCheckerService.java index 35a5c0f52..973a448ee 100644 --- a/java/src/com/android/inputmethod/latin/spellcheck/AndroidSpellCheckerService.java +++ b/java/src/com/android/inputmethod/latin/spellcheck/AndroidSpellCheckerService.java @@ -570,7 +570,11 @@ public class AndroidSpellCheckerService extends SpellCheckerService final WordComposer composer = new WordComposer(); final int length = text.length(); for (int i = 0; i < length; i = text.offsetByCodePoints(i, 1)) { - composer.addKeyForSpellChecker(text.codePointAt(i), mScript); + final int codePoint = text.codePointAt(i); + // The getXYForCodePointAndScript method returns (Y << 16) + X + final int xy = SpellCheckerProximityInfo.getXYForCodePointAndScript( + codePoint, mScript); + composer.add(codePoint, xy & 0xFFFF, xy >> 16, null); } final int capitalizeType = getCapitalizationType(text); diff --git a/java/src/com/android/inputmethod/latin/spellcheck/SpellCheckerProximityInfo.java b/java/src/com/android/inputmethod/latin/spellcheck/SpellCheckerProximityInfo.java index f4c66d04c..90c0aac1b 100644 --- a/java/src/com/android/inputmethod/latin/spellcheck/SpellCheckerProximityInfo.java +++ b/java/src/com/android/inputmethod/latin/spellcheck/SpellCheckerProximityInfo.java @@ -87,7 +87,7 @@ public class SpellCheckerProximityInfo { // Proximity for row 2. See comment above about size. 'a', 'z', 'x', 's', 'w', 'q', 'e', 'i', 'o', 'u', NUL, NUL, NUL, NUL, NUL, NUL, 's', 'q', 'a', 'z', 'x', 'c', 'd', 'e', 'w', NUL, NUL, NUL, NUL, NUL, NUL, NUL, - 'd', 'w', 's', 'x', 'c', 'v', 'f', 'r', 'e', 'w', NUL, NUL, NUL, NUL, NUL, NUL, + 'd', 'w', 's', 'x', 'c', 'v', 'f', 'r', 'e', NUL, NUL, NUL, NUL, NUL, NUL, NUL, 'f', 'e', 'd', 'c', 'v', 'b', 'g', 't', 'r', NUL, NUL, NUL, NUL, NUL, NUL, NUL, 'g', 'r', 'f', 'v', 'b', 'n', 'h', 'y', 't', NUL, NUL, NUL, NUL, NUL, NUL, NUL, 'h', 't', 'g', 'b', 'n', 'm', 'j', 'u', 'y', NUL, NUL, NUL, NUL, NUL, NUL, NUL, @@ -181,14 +181,30 @@ public class SpellCheckerProximityInfo { throw new RuntimeException("Wrong script supplied: " + script); } } - public static int getIndexOfCodeForScript(final int characterCode, final int script) { + + private static int getIndexOfCodeForScript(final int codePoint, final int script) { switch (script) { case AndroidSpellCheckerService.SCRIPT_LATIN: - return Latin.getIndexOf(characterCode); + return Latin.getIndexOf(codePoint); case AndroidSpellCheckerService.SCRIPT_CYRILLIC: - return Cyrillic.getIndexOf(characterCode); + return Cyrillic.getIndexOf(codePoint); default: throw new RuntimeException("Wrong script supplied: " + script); } } + + // Returns (Y << 16) + X to avoid creating a temporary object. This is okay because + // X and Y are limited to PROXIMITY_GRID_WIDTH resp. PROXIMITY_GRID_HEIGHT which is very + // inferior to 1 << 16 + public static int getXYForCodePointAndScript(final int codePoint, final int script) { + final int index = getIndexOfCodeForScript(codePoint, script); + // TODO: precompute index / ROW_SIZE + final int y = index / (PROXIMITY_GRID_WIDTH * ROW_SIZE); + final int x = (index / ROW_SIZE) % PROXIMITY_GRID_WIDTH; + if (y > PROXIMITY_GRID_HEIGHT) { + // Safety check, should be entirely useless + throw new RuntimeException("Wrong y coordinate in spell checker proximity"); + } + return (y << 16) + x; + } } diff --git a/native/src/proximity_info.cpp b/native/src/proximity_info.cpp index 4d03f3274..47f137610 100644 --- a/native/src/proximity_info.cpp +++ b/native/src/proximity_info.cpp @@ -130,6 +130,7 @@ bool ProximityInfo::hasSpaceProximity(const int x, const int y) const { } bool ProximityInfo::isOnKey(const int keyId, const int x, const int y) { + if (keyId < 0) return true; // NOT_A_ID is -1, but return whenever < 0 just in case const int left = mKeyXCoordinates[keyId]; const int top = mKeyYCoordinates[keyId]; const int right = left + mKeyWidths[keyId] + 1; @@ -138,6 +139,7 @@ bool ProximityInfo::isOnKey(const int keyId, const int x, const int y) { } int ProximityInfo::squaredDistanceToEdge(const int keyId, const int x, const int y) { + if (keyId < 0) return true; // NOT_A_ID is -1, but return whenever < 0 just in case const int left = mKeyXCoordinates[keyId]; const int top = mKeyYCoordinates[keyId]; const int right = left + mKeyWidths[keyId]; @@ -162,7 +164,7 @@ void ProximityInfo::calculateNearbyKeyCodes( const int keyIndex = getKeyIndex(c); const bool onKey = isOnKey(keyIndex, x, y); const int distance = squaredDistanceToEdge(keyIndex, x, y); - if (c >= KEYCODE_SPACE && (onKey || distance < MOST_COMMON_KEY_WIDTH_SQUARE)) { + if (onKey || distance < MOST_COMMON_KEY_WIDTH_SQUARE) { inputCodes[insertPos++] = c; if (insertPos >= MAX_PROXIMITY_CHARS_SIZE) { if (DEBUG_DICT) { @@ -211,7 +213,6 @@ void ProximityInfo::calculateNearbyKeyCodes( } } -// TODO: Calculate nearby codes here. void ProximityInfo::setInputParams(const int32_t* inputCodes, const int inputLength, const int* xCoordinates, const int* yCoordinates) { memset(mInputCodes, 0,