diff options
Diffstat (limited to 'java/src/com/android/inputmethod/latin/spellcheck')
-rw-r--r-- | java/src/com/android/inputmethod/latin/spellcheck/AndroidSpellCheckerService.java | 17 | ||||
-rw-r--r-- | java/src/com/android/inputmethod/latin/spellcheck/SpellCheckerProximityInfo.java | 51 |
2 files changed, 58 insertions, 10 deletions
diff --git a/java/src/com/android/inputmethod/latin/spellcheck/AndroidSpellCheckerService.java b/java/src/com/android/inputmethod/latin/spellcheck/AndroidSpellCheckerService.java index 35a5c0f52..5a173857e 100644 --- a/java/src/com/android/inputmethod/latin/spellcheck/AndroidSpellCheckerService.java +++ b/java/src/com/android/inputmethod/latin/spellcheck/AndroidSpellCheckerService.java @@ -353,6 +353,11 @@ public class AndroidSpellCheckerService extends SpellCheckerService @Override public boolean onUnbind(final Intent intent) { + closeAllDictionaries(); + return false; + } + + private void closeAllDictionaries() { final Map<String, DictionaryPool> oldPools = mDictionaryPools; mDictionaryPools = Collections.synchronizedMap(new TreeMap<String, DictionaryPool>()); final Map<String, Dictionary> oldUserDictionaries = mUserDictionaries; @@ -378,7 +383,6 @@ public class AndroidSpellCheckerService extends SpellCheckerService dictToClose.close(); } } - return false; } private DictionaryPool getDictionaryPool(final String locale) { @@ -570,7 +574,16 @@ 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); + if (SpellCheckerProximityInfo.NOT_A_COORDINATE_PAIR == xy) { + composer.add(codePoint, WordComposer.NOT_A_COORDINATE, + WordComposer.NOT_A_COORDINATE, null); + } else { + 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 db3544987..0103e8423 100644 --- a/java/src/com/android/inputmethod/latin/spellcheck/SpellCheckerProximityInfo.java +++ b/java/src/com/android/inputmethod/latin/spellcheck/SpellCheckerProximityInfo.java @@ -30,17 +30,25 @@ public class SpellCheckerProximityInfo { // as the size of the passed array afterwards so they can't be different. final public static int ROW_SIZE = ProximityInfo.MAX_PROXIMITY_CHARS_SIZE; + // The number of keys in a row of the grid used by the spell checker. + final public static int PROXIMITY_GRID_WIDTH = 11; + // The number of rows in the grid used by the spell checker. + final public static int PROXIMITY_GRID_HEIGHT = 3; + + final private static int NOT_AN_INDEX = -1; + final public static int NOT_A_COORDINATE_PAIR = -1; + // Helper methods final protected static void buildProximityIndices(final int[] proximity, final TreeMap<Integer, Integer> indices) { for (int i = 0; i < proximity.length; i += ROW_SIZE) { - if (NUL != proximity[i]) indices.put(proximity[i], i); + if (NUL != proximity[i]) indices.put(proximity[i], i / ROW_SIZE); } } final protected static int computeIndex(final int characterCode, final TreeMap<Integer, Integer> indices) { final Integer result = indices.get(characterCode); - if (null == result) return -1; + if (null == result) return NOT_AN_INDEX; return result; } @@ -64,6 +72,9 @@ public class SpellCheckerProximityInfo { // to English, many spelling errors consist of the last vowel of the word being wrong // because in English vowels tend to merge with each other in pronunciation. final static int[] PROXIMITY = { + // Proximity for row 1. This must have exactly ROW_SIZE entries for each letter, + // and exactly PROXIMITY_GRID_WIDTH letters for a row. Pad with NUL's. + // The number of rows must be exactly PROXIMITY_GRID_HEIGHT. 'q', 'w', 's', 'a', 'z', NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, 'w', 'q', 'a', 's', 'd', 'e', 'x', NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, 'e', 'w', 's', 'd', 'f', 'r', 'a', 'i', 'o', 'u', NUL, NUL, NUL, NUL, NUL, NUL, @@ -76,9 +87,10 @@ public class SpellCheckerProximityInfo { 'p', 'o', 'l', NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, + // 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, @@ -88,6 +100,7 @@ public class SpellCheckerProximityInfo { NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, + // Proximity for row 3. See comment above about size. 'z', 'a', 's', 'd', 'x', 't', 'g', 'h', 'j', 'u', 'q', 'e', NUL, NUL, NUL, NUL, 'x', 'z', 'a', 's', 'd', 'c', NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, 'c', 'x', 's', 'd', 'f', 'v', NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, @@ -109,9 +122,12 @@ public class SpellCheckerProximityInfo { private static class Cyrillic { final private static TreeMap<Integer, Integer> INDICES = new TreeMap<Integer, Integer>(); + // TODO: The following table is solely based on the keyboard layout. Consult with Russian + // speakers on commonly misspelled words/letters. final static int[] PROXIMITY = { - // TODO: This table is solely based on the keyboard layout. Consult with Russian - // speakers on commonly misspelled words/letters. + // Proximity for row 1. This must have exactly ROW_SIZE entries for each letter, + // and exactly PROXIMITY_GRID_WIDTH letters for a row. Pad with NUL's. + // The number of rows must be exactly PROXIMITY_GRID_HEIGHT. 'й', 'ц', 'ф', 'ы', NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, 'ц', 'й', 'ф', 'ы', 'в', 'у', NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, 'у', 'ц', 'ы', 'в', 'а', 'к', NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, @@ -124,6 +140,7 @@ public class SpellCheckerProximityInfo { 'з', 'щ', 'д', 'ж', 'э', 'х', NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, 'х', 'з', 'ж', 'э', NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, + // Proximity for row 2. See comment above about size. 'ф', 'й', 'ц', 'ы', 'я', NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, 'ы', 'й', 'ц', 'у', 'ф', 'в', 'я', 'ч', NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, 'в', 'ц', 'у', 'к', 'ы', 'а', 'я', 'ч', 'с', NUL, NUL, NUL, NUL, NUL, NUL, NUL, @@ -136,6 +153,7 @@ public class SpellCheckerProximityInfo { 'ж', 'щ', 'з', 'х', 'д', 'э', 'б', 'ю', NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, 'э', 'з', 'х', 'ю', NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, + // Proximity for row 3. See comment above about size. 'я', 'ф', 'ы', 'в', 'ч', NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, 'ч', 'ы', 'в', 'а', 'я', 'с', NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, 'с', 'в', 'а', 'п', 'ч', 'м', NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, @@ -166,14 +184,31 @@ 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 + // As an exception, this returns NOT_A_COORDINATE_PAIR if the key is not on the grid + public static int getXYForCodePointAndScript(final int codePoint, final int script) { + final int index = getIndexOfCodeForScript(codePoint, script); + if (NOT_AN_INDEX == index) return NOT_A_COORDINATE_PAIR; + final int y = index / PROXIMITY_GRID_WIDTH; + final int x = index % 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; + } } |