From 1830cd1dc8259aa57175f1cf2a3d8797a7a35935 Mon Sep 17 00:00:00 2001 From: Jean Chalard Date: Thu, 8 Dec 2011 16:52:08 +0900 Subject: [PATCH] Add proximity for Russian. This also tries to make the code as easy to extend as possible for future developments. Bug: 5701241 Change-Id: I1ed48e6a5cc7aab94c5d6e309930cc004247d7e7 --- .../inputmethod/keyboard/ProximityInfo.java | 4 +- .../AndroidSpellCheckerService.java | 67 +++--- .../spellcheck/SpellCheckerProximityInfo.java | 197 +++++++++++++----- 3 files changed, 182 insertions(+), 86 deletions(-) diff --git a/java/src/com/android/inputmethod/keyboard/ProximityInfo.java b/java/src/com/android/inputmethod/keyboard/ProximityInfo.java index 6c5c3e7be..778aac3de 100644 --- a/java/src/com/android/inputmethod/keyboard/ProximityInfo.java +++ b/java/src/com/android/inputmethod/keyboard/ProximityInfo.java @@ -65,12 +65,12 @@ public class ProximityInfo { return new ProximityInfo(1, 1, 1, 1, 1, 1, Collections.emptyList(), null); } - public static ProximityInfo createSpellCheckerProximityInfo() { + public static ProximityInfo createSpellCheckerProximityInfo(final int[] proximity) { final ProximityInfo spellCheckerProximityInfo = createDummyProximityInfo(); spellCheckerProximityInfo.mNativeProximityInfo = spellCheckerProximityInfo.setProximityInfoNative( SpellCheckerProximityInfo.ROW_SIZE, - 480, 300, 10, 3, SpellCheckerProximityInfo.PROXIMITY, + 480, 300, 11, 3, proximity, 0, null, null, null, null, null, null, null, null); return spellCheckerProximityInfo; } diff --git a/java/src/com/android/inputmethod/latin/spellcheck/AndroidSpellCheckerService.java b/java/src/com/android/inputmethod/latin/spellcheck/AndroidSpellCheckerService.java index a89ef001e..8b6ecbef9 100644 --- a/java/src/com/android/inputmethod/latin/spellcheck/AndroidSpellCheckerService.java +++ b/java/src/com/android/inputmethod/latin/spellcheck/AndroidSpellCheckerService.java @@ -99,6 +99,25 @@ public class AndroidSpellCheckerService extends SpellCheckerService private final HashSet> mDictionaryCollectionsList = new HashSet>(); + public static final int SCRIPT_LATIN = 0; + public static final int SCRIPT_CYRILLIC = 1; + private static final TreeMap mLanguageToScript; + static { + // List of the supported languages and their associated script. We won't check + // words written in another script than the selected script, because we know we + // don't have those in our dictionary so we will underline everything and we + // will never have any suggestions, so it makes no sense checking them. + mLanguageToScript = new TreeMap(); + mLanguageToScript.put("en", SCRIPT_LATIN); + mLanguageToScript.put("fr", SCRIPT_LATIN); + mLanguageToScript.put("de", SCRIPT_LATIN); + mLanguageToScript.put("nl", SCRIPT_LATIN); + mLanguageToScript.put("cs", SCRIPT_LATIN); + mLanguageToScript.put("es", SCRIPT_LATIN); + mLanguageToScript.put("it", SCRIPT_LATIN); + mLanguageToScript.put("ru", SCRIPT_CYRILLIC); + } + @Override public void onCreate() { super.onCreate(); mSuggestionThreshold = @@ -110,6 +129,15 @@ public class AndroidSpellCheckerService extends SpellCheckerService onSharedPreferenceChanged(prefs, PREF_USE_CONTACTS_KEY); } + private static int getScriptFromLocale(final Locale locale) { + final Integer script = mLanguageToScript.get(locale.getLanguage()); + if (null == script) { + throw new RuntimeException("We have been called with an unsupported language: \"" + + locale.getLanguage() + "\". Framework bug?"); + } + return script; + } + @Override public void onSharedPreferenceChanged(final SharedPreferences prefs, final String key) { if (!PREF_USE_CONTACTS_KEY.equals(key)) return; @@ -363,7 +391,9 @@ public class AndroidSpellCheckerService extends SpellCheckerService } public DictAndProximity createDictAndProximity(final Locale locale) { - final ProximityInfo proximityInfo = ProximityInfo.createSpellCheckerProximityInfo(); + final int script = getScriptFromLocale(locale); + final ProximityInfo proximityInfo = ProximityInfo.createSpellCheckerProximityInfo( + SpellCheckerProximityInfo.getProximityForScript(script)); final Resources resources = getResources(); final int fallbackResourceId = Utils.getMainDictionaryResourceId(resources); final DictionaryCollection dictionaryCollection = @@ -415,25 +445,6 @@ public class AndroidSpellCheckerService extends SpellCheckerService } private static class AndroidSpellCheckerSession extends Session { - private static final int SCRIPT_LATIN = 0; - private static final int SCRIPT_CYRILLIC = 1; - private static final TreeMap mLanguageToScript; - static { - // List of the supported languages and their associated script. We won't check - // words written in another script than the selected script, because we know we - // don't have those in our dictionary so we will underline everything and we - // will never have any suggestions, so it makes no sense checking them. - mLanguageToScript = new TreeMap(); - mLanguageToScript.put("en", SCRIPT_LATIN); - mLanguageToScript.put("fr", SCRIPT_LATIN); - mLanguageToScript.put("de", SCRIPT_LATIN); - mLanguageToScript.put("nl", SCRIPT_LATIN); - mLanguageToScript.put("cs", SCRIPT_LATIN); - mLanguageToScript.put("es", SCRIPT_LATIN); - mLanguageToScript.put("it", SCRIPT_LATIN); - mLanguageToScript.put("ru", SCRIPT_CYRILLIC); - } - // Immutable, but need the locale which is not available in the constructor yet private DictionaryPool mDictionaryPool; // Likewise @@ -452,12 +463,7 @@ public class AndroidSpellCheckerService extends SpellCheckerService final String localeString = getLocale(); mDictionaryPool = mService.getDictionaryPool(localeString); mLocale = LocaleUtils.constructLocaleFromString(localeString); - final Integer script = mLanguageToScript.get(mLocale.getLanguage()); - if (null == script) { - throw new RuntimeException("We have been called with an unsupported language: \"" - + mLocale.getLanguage() + "\". Framework bug?"); - } - mScript = script; + mScript = getScriptFromLocale(mLocale); } /* @@ -565,12 +571,17 @@ public class AndroidSpellCheckerService extends SpellCheckerService final int length = text.length(); for (int i = 0; i < length; ++i) { final int character = text.codePointAt(i); - final int proximityIndex = SpellCheckerProximityInfo.getIndexOf(character); + final int proximityIndex = + SpellCheckerProximityInfo.getIndexOfCodeForScript(character, mScript); final int[] proximities; if (-1 == proximityIndex) { proximities = new int[] { character }; } else { - proximities = Arrays.copyOfRange(SpellCheckerProximityInfo.PROXIMITY, + // 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(mScript), proximityIndex, proximityIndex + SpellCheckerProximityInfo.ROW_SIZE); } diff --git a/java/src/com/android/inputmethod/latin/spellcheck/SpellCheckerProximityInfo.java b/java/src/com/android/inputmethod/latin/spellcheck/SpellCheckerProximityInfo.java index d5b04b27c..9a2bebfdf 100644 --- a/java/src/com/android/inputmethod/latin/spellcheck/SpellCheckerProximityInfo.java +++ b/java/src/com/android/inputmethod/latin/spellcheck/SpellCheckerProximityInfo.java @@ -29,65 +29,150 @@ 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; - // This is a map from the code point to the index in the PROXIMITY array. - // At the time the native code to read the binary dictionary needs the proximity info be passed - // as a flat array spaced by MAX_PROXIMITY_CHARS_SIZE columns, one for each input character. - // Since we need to build such an array, we want to be able to search in our big proximity data - // quickly by character, and a map is probably the best way to do this. - final private static TreeMap INDICES = new TreeMap(); - - // The proximity here is the union of - // - the proximity for a QWERTY keyboard. - // - the proximity for an AZERTY keyboard. - // - the proximity for a QWERTZ keyboard. - // ...plus, add all characters in the ('a', 'e', 'i', 'o', 'u') set to each other. - // - // The reasoning behind this construction is, almost any alphabetic text we may want - // to spell check has been entered with one of the keyboards above. Also, specifically - // 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 public static int[] PROXIMITY = { - '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, - 'r', 'e', 'd', 'f', 'g', 't', NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, - 't', 'r', 'f', 'g', 'h', 'y', NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, - 'y', 't', 'g', 'h', 'j', 'u', 'a', 's', 'd', 'x', NUL, NUL, NUL, NUL, NUL, NUL, - 'u', 'y', 'h', 'j', 'k', 'i', 'a', 'e', 'o', NUL, NUL, NUL, NUL, NUL, NUL, NUL, - 'i', 'u', 'j', 'k', 'l', 'o', 'a', 'e', NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, - 'o', 'i', 'k', 'l', 'p', 'a', 'e', 'u', NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, - 'p', 'o', 'l', NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, - - '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, - '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, - 'j', 'y', 'h', 'n', 'm', 'k', 'i', 'u', NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, - 'k', 'u', 'j', 'm', 'l', 'o', 'i', NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, - 'l', 'i', 'k', 'p', 'o', 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, - - '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, - 'v', 'c', 'd', 'f', 'g', 'b', NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, - 'b', 'v', 'f', 'g', 'h', 'n', NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, - 'n', 'b', 'g', 'h', 'j', 'm', NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, - 'm', 'n', 'h', 'j', 'k', 'l', 'o', 'p', 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, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, - NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, - }; - static { - for (int i = 0; i < PROXIMITY.length; i += ROW_SIZE) { - if (NUL != PROXIMITY[i]) INDICES.put(PROXIMITY[i], i); + // Helper methods + final protected static void buildProximityIndices(final int[] proximity, + final TreeMap indices) { + for (int i = 0; i < proximity.length; i += ROW_SIZE) { + if (NUL != proximity[i]) indices.put(proximity[i], i); } } - public static int getIndexOf(int characterCode) { - final Integer result = INDICES.get(characterCode); + final protected static int computeIndex(final int characterCode, + final TreeMap indices) { + final Integer result = indices.get(characterCode); if (null == result) return -1; return result; } + + static class Latin { + // This is a map from the code point to the index in the PROXIMITY array. + // At the time the native code to read the binary dictionary needs the proximity info be + // passed as a flat array spaced by MAX_PROXIMITY_CHARS_SIZE columns, one for each input + // character. + // Since we need to build such an array, we want to be able to search in our big proximity + // data quickly by character, and a map is probably the best way to do this. + final private static TreeMap INDICES = new TreeMap(); + + // The proximity here is the union of + // - the proximity for a QWERTY keyboard. + // - the proximity for an AZERTY keyboard. + // - the proximity for a QWERTZ keyboard. + // ...plus, add all characters in the ('a', 'e', 'i', 'o', 'u') set to each other. + // + // The reasoning behind this construction is, almost any alphabetic text we may want + // to spell check has been entered with one of the keyboards above. Also, specifically + // 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 private static int[] PROXIMITY = { + '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, + 'r', 'e', 'd', 'f', 'g', 't', NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, + 't', 'r', 'f', 'g', 'h', 'y', NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, + 'y', 't', 'g', 'h', 'j', 'u', 'a', 's', 'd', 'x', NUL, NUL, NUL, NUL, NUL, NUL, + 'u', 'y', 'h', 'j', 'k', 'i', 'a', 'e', 'o', NUL, NUL, NUL, NUL, NUL, NUL, NUL, + 'i', 'u', 'j', 'k', 'l', 'o', 'a', 'e', NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, + 'o', 'i', 'k', 'l', 'p', 'a', 'e', 'u', NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, + '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, + + '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, + '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, + 'j', 'y', 'h', 'n', 'm', 'k', 'i', 'u', NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, + 'k', 'u', 'j', 'm', 'l', 'o', 'i', NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, + 'l', 'i', 'k', 'p', 'o', 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, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, + + '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, + 'v', 'c', 'd', 'f', 'g', 'b', NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, + 'b', 'v', 'f', 'g', 'h', 'n', NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, + 'n', 'b', 'g', 'h', 'j', 'm', NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, + 'm', 'n', 'h', 'j', 'k', 'l', 'o', 'p', 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, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, + NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, + }; + static { + buildProximityIndices(PROXIMITY, INDICES); + } + private static int getIndexOf(int characterCode) { + return computeIndex(characterCode, INDICES); + } + } + + static class Cyrillic { + final private static TreeMap INDICES = new TreeMap(); + final private static int[] PROXIMITY = { + // TODO: This table is solely based on the keyboard layout. Consult with Russian + // speakers on commonly misspelled words/letters. + 'й', 'ц', 'ф', 'ы', 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, + 'к', 'у', 'в', 'а', 'п', 'е', 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, 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, 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, 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, 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, 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, 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, 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, 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, NUL, NUL, NUL, NUL, NUL, NUL, + }; + static { + buildProximityIndices(PROXIMITY, INDICES); + } + private static int getIndexOf(int characterCode) { + return computeIndex(characterCode, INDICES); + } + } + + public static int[] getProximityForScript(final int script) { + switch (script) { + case AndroidSpellCheckerService.SCRIPT_LATIN: + return Latin.PROXIMITY; + case AndroidSpellCheckerService.SCRIPT_CYRILLIC: + return Cyrillic.PROXIMITY; + default: + throw new RuntimeException("Wrong script supplied: " + script); + } + } + public static int getIndexOfCodeForScript(final int characterCode, final int script) { + switch (script) { + case AndroidSpellCheckerService.SCRIPT_LATIN: + return Latin.getIndexOf(characterCode); + case AndroidSpellCheckerService.SCRIPT_CYRILLIC: + return Cyrillic.getIndexOf(characterCode); + default: + throw new RuntimeException("Wrong script supplied: " + script); + } + } }