From 673cebf9e97289b3b0cd343ff7193dff69684a48 Mon Sep 17 00:00:00 2001 From: Jean Chalard Date: Thu, 29 Sep 2011 21:07:22 +0900 Subject: [PATCH] Make use of the FULL_EDIT_DISTANCE flag. In effect, this stops the spell checker from suggesting overly long words. More precisely, it takes advantage of the new facility that takes into account the whole length of the dictionary word when computing scores, so words much longer than the input word will see their score demoted accordingly. Bug: 5384578 Change-Id: I326cd7c87c3080e7fa8729f78517f8ba13672a9b --- .../inputmethod/latin/BinaryDictionary.java | 14 +++++++++-- .../inputmethod/latin/DictionaryFactory.java | 25 ++++++++++++++++--- .../AndroidSpellCheckerService.java | 16 +++++++++++- 3 files changed, 48 insertions(+), 7 deletions(-) diff --git a/java/src/com/android/inputmethod/latin/BinaryDictionary.java b/java/src/com/android/inputmethod/latin/BinaryDictionary.java index ab9edb110..18a9e3ab1 100644 --- a/java/src/com/android/inputmethod/latin/BinaryDictionary.java +++ b/java/src/com/android/inputmethod/latin/BinaryDictionary.java @@ -61,16 +61,26 @@ public class BinaryDictionary extends Dictionary { public static final Flag FLAG_REQUIRES_GERMAN_UMLAUT_PROCESSING = new Flag(R.bool.config_require_umlaut_processing, 0x1); + // FULL_EDIT_DISTANCE is a flag that forces the dictionary to use full words + // when computing edit distance, instead of the default behavior of stopping + // the evaluation at the size the user typed. public static final Flag FLAG_USE_FULL_EDIT_DISTANCE = new Flag(0x2); // Can create a new flag from extravalue : // public static final Flag FLAG_MYFLAG = // new Flag("my_flag", 0x02); - private static final Flag[] ALL_FLAGS = { + // ALL_CONFIG_FLAGS is a collection of flags that enable reading all flags from configuration. + // This is but a mask - it does not mean the flags will be on, only that the configuration + // will be read for this particular flag. + public static final Flag[] ALL_CONFIG_FLAGS = { // Here should reside all flags that trigger some special processing // These *must* match the definition in UnigramDictionary enum in // unigram_dictionary.h so please update both at the same time. + // Please note that flags created with a resource are of type CONFIG while flags + // created with a string are of type EXTRAVALUE. These behave like masks, and the + // actual value will be read from the configuration/extra value at run time for + // the configuration at dictionary creation time. FLAG_REQUIRES_GERMAN_UMLAUT_PROCESSING, }; @@ -93,7 +103,7 @@ public class BinaryDictionary extends Dictionary { // the Suggest class knows everything about every single dictionary. mDicTypeId = Suggest.DIC_MAIN; // TODO: Stop relying on the state of SubtypeSwitcher, get it as a parameter - mFlags = Flag.initFlags(null == flagArray ? ALL_FLAGS : flagArray, context, + mFlags = Flag.initFlags(null == flagArray ? ALL_CONFIG_FLAGS : flagArray, context, SubtypeSwitcher.getInstance()); loadDictionary(filename, offset, length); } diff --git a/java/src/com/android/inputmethod/latin/DictionaryFactory.java b/java/src/com/android/inputmethod/latin/DictionaryFactory.java index dfaad26bc..1607f86a8 100644 --- a/java/src/com/android/inputmethod/latin/DictionaryFactory.java +++ b/java/src/com/android/inputmethod/latin/DictionaryFactory.java @@ -34,7 +34,7 @@ public class DictionaryFactory { private static String TAG = DictionaryFactory.class.getSimpleName(); /** - * Initializes a dictionary from a dictionary pack. + * Initializes a dictionary from a dictionary pack, with explicit flags. * * This searches for a content provider providing a dictionary pack for the specified * locale. If none is found, it falls back to using the resource passed as fallBackResId @@ -42,10 +42,11 @@ public class DictionaryFactory { * @param context application context for reading resources * @param locale the locale for which to create the dictionary * @param fallbackResId the id of the resource to use as a fallback if no pack is found + * @param flagArray an array of flags to use * @return an initialized instance of DictionaryCollection */ - public static DictionaryCollection createDictionaryFromManager(Context context, Locale locale, - int fallbackResId) { + public static DictionaryCollection createDictionaryFromManager(final Context context, + final Locale locale, final int fallbackResId, final Flag[] flagArray) { if (null == locale) { Log.e(TAG, "No locale defined for dictionary"); return new DictionaryCollection(createBinaryDictionary(context, fallbackResId, locale)); @@ -57,7 +58,7 @@ public class DictionaryFactory { if (null != assetFileList) { for (final AssetFileAddress f : assetFileList) { final BinaryDictionary binaryDictionary = - new BinaryDictionary(context, f.mFilename, f.mOffset, f.mLength, null); + new BinaryDictionary(context, f.mFilename, f.mOffset, f.mLength, flagArray); if (binaryDictionary.isValidDictionary()) { dictList.add(binaryDictionary); } @@ -70,6 +71,22 @@ public class DictionaryFactory { return new DictionaryCollection(dictList); } + /** + * Initializes a dictionary from a dictionary pack, with default flags. + * + * This searches for a content provider providing a dictionary pack for the specified + * locale. If none is found, it falls back to using the resource passed as fallBackResId + * as a dictionary. + * @param context application context for reading resources + * @param locale the locale for which to create the dictionary + * @param fallbackResId the id of the resource to use as a fallback if no pack is found + * @return an initialized instance of DictionaryCollection + */ + public static DictionaryCollection createDictionaryFromManager(final Context context, + final Locale locale, final int fallbackResId) { + return createDictionaryFromManager(context, locale, fallbackResId, null); + } + /** * Initializes a dictionary from a raw resource file * @param context application context for reading resources diff --git a/java/src/com/android/inputmethod/latin/spellcheck/AndroidSpellCheckerService.java b/java/src/com/android/inputmethod/latin/spellcheck/AndroidSpellCheckerService.java index 1d5986ef9..9e030eb90 100644 --- a/java/src/com/android/inputmethod/latin/spellcheck/AndroidSpellCheckerService.java +++ b/java/src/com/android/inputmethod/latin/spellcheck/AndroidSpellCheckerService.java @@ -28,11 +28,13 @@ import android.text.TextUtils; import com.android.inputmethod.compat.ArraysCompatUtils; import com.android.inputmethod.keyboard.Key; import com.android.inputmethod.keyboard.ProximityInfo; +import com.android.inputmethod.latin.BinaryDictionary; import com.android.inputmethod.latin.Dictionary; import com.android.inputmethod.latin.Dictionary.DataType; import com.android.inputmethod.latin.Dictionary.WordCallback; import com.android.inputmethod.latin.DictionaryCollection; import com.android.inputmethod.latin.DictionaryFactory; +import com.android.inputmethod.latin.Flag; import com.android.inputmethod.latin.LocaleUtils; import com.android.inputmethod.latin.R; import com.android.inputmethod.latin.SynchronouslyLoadedUserDictionary; @@ -65,6 +67,17 @@ public class AndroidSpellCheckerService extends SpellCheckerService { private final static SuggestionsInfo IN_DICT_EMPTY_SUGGESTIONS = new SuggestionsInfo(SuggestionsInfo.RESULT_ATTR_IN_THE_DICTIONARY, EMPTY_STRING_ARRAY); + private final static Flag[] USE_FULL_EDIT_DISTANCE_FLAG_ARRAY; + static { + // See BinaryDictionary.java for an explanation of these flags + // Specifially, ALL_CONFIG_FLAGS means that we want to consider all flags with the + // current dictionary configuration - for example, consider the UMLAUT flag + // so that it will be turned on for German dictionaries and off for others. + USE_FULL_EDIT_DISTANCE_FLAG_ARRAY = Arrays.copyOf(BinaryDictionary.ALL_CONFIG_FLAGS, + BinaryDictionary.ALL_CONFIG_FLAGS.length + 1); + USE_FULL_EDIT_DISTANCE_FLAG_ARRAY[BinaryDictionary.ALL_CONFIG_FLAGS.length] = + BinaryDictionary.FLAG_USE_FULL_EDIT_DISTANCE; + } private Map mDictionaryPools = Collections.synchronizedMap(new TreeMap()); private Map mUserDictionaries = @@ -263,7 +276,8 @@ public class AndroidSpellCheckerService extends SpellCheckerService { final Resources resources = getResources(); final int fallbackResourceId = Utils.getMainDictionaryResourceId(resources); final DictionaryCollection dictionaryCollection = - DictionaryFactory.createDictionaryFromManager(this, locale, fallbackResourceId); + DictionaryFactory.createDictionaryFromManager(this, locale, fallbackResourceId, + USE_FULL_EDIT_DISTANCE_FLAG_ARRAY); final String localeStr = locale.toString(); Dictionary userDict = mUserDictionaries.get(localeStr); if (null == userDict) {