aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--dictionary/jni/com_android_inputmethod_latin_BinaryDictionary.cpp9
-rw-r--r--dictionary/src/dictionary.cpp26
-rw-r--r--dictionary/src/dictionary.h6
-rw-r--r--src/com/android/inputmethod/latin/BinaryDictionary.java13
-rw-r--r--src/com/android/inputmethod/latin/ContactsDictionary.java5
-rw-r--r--src/com/android/inputmethod/latin/Dictionary.java7
-rw-r--r--src/com/android/inputmethod/latin/ExpandableDictionary.java10
-rw-r--r--src/com/android/inputmethod/latin/LatinIME.java6
-rw-r--r--src/com/android/inputmethod/latin/LatinKeyboard.java110
-rw-r--r--src/com/android/inputmethod/latin/LatinKeyboardView.java19
-rwxr-xr-xsrc/com/android/inputmethod/latin/Suggest.java19
-rw-r--r--src/com/android/inputmethod/latin/UserDictionary.java5
12 files changed, 215 insertions, 20 deletions
diff --git a/dictionary/jni/com_android_inputmethod_latin_BinaryDictionary.cpp b/dictionary/jni/com_android_inputmethod_latin_BinaryDictionary.cpp
index 3076085e4..3dda062fe 100644
--- a/dictionary/jni/com_android_inputmethod_latin_BinaryDictionary.cpp
+++ b/dictionary/jni/com_android_inputmethod_latin_BinaryDictionary.cpp
@@ -89,7 +89,7 @@ static jint latinime_BinaryDictionary_open
static int latinime_BinaryDictionary_getSuggestions(
JNIEnv *env, jobject object, jint dict, jintArray inputArray, jint arraySize,
jcharArray outputArray, jintArray frequencyArray, jint maxWordLength, jint maxWords,
- jint maxAlternatives, jint skipPos)
+ jint maxAlternatives, jint skipPos, jintArray nextLettersArray, jint nextLettersSize)
{
Dictionary *dictionary = (Dictionary*) dict;
if (dictionary == NULL)
@@ -98,13 +98,16 @@ static int latinime_BinaryDictionary_getSuggestions(
int *frequencies = env->GetIntArrayElements(frequencyArray, NULL);
int *inputCodes = env->GetIntArrayElements(inputArray, NULL);
jchar *outputChars = env->GetCharArrayElements(outputArray, NULL);
+ int *nextLetters = nextLettersArray != NULL ? env->GetIntArrayElements(nextLettersArray, NULL)
+ : NULL;
int count = dictionary->getSuggestions(inputCodes, arraySize, (unsigned short*) outputChars, frequencies,
- maxWordLength, maxWords, maxAlternatives, skipPos);
+ maxWordLength, maxWords, maxAlternatives, skipPos, nextLetters, nextLettersSize);
env->ReleaseIntArrayElements(frequencyArray, frequencies, 0);
env->ReleaseIntArrayElements(inputArray, inputCodes, JNI_ABORT);
env->ReleaseCharArrayElements(outputArray, outputChars, 0);
+ env->ReleaseIntArrayElements(nextLettersArray, nextLetters, 0);
return count;
}
@@ -136,7 +139,7 @@ static JNINativeMethod gMethods[] = {
{"openNative", "(Landroid/content/res/AssetManager;Ljava/lang/String;II)I",
(void*)latinime_BinaryDictionary_open},
{"closeNative", "(I)V", (void*)latinime_BinaryDictionary_close},
- {"getSuggestionsNative", "(I[II[C[IIIII)I", (void*)latinime_BinaryDictionary_getSuggestions},
+ {"getSuggestionsNative", "(I[II[C[IIIII[II)I", (void*)latinime_BinaryDictionary_getSuggestions},
{"isValidWordNative", "(I[CI)Z", (void*)latinime_BinaryDictionary_isValidWord}
};
diff --git a/dictionary/src/dictionary.cpp b/dictionary/src/dictionary.cpp
index 306aff527..6e6f44182 100644
--- a/dictionary/src/dictionary.cpp
+++ b/dictionary/src/dictionary.cpp
@@ -49,7 +49,8 @@ Dictionary::~Dictionary()
}
int Dictionary::getSuggestions(int *codes, int codesSize, unsigned short *outWords, int *frequencies,
- int maxWordLength, int maxWords, int maxAlternatives, int skipPos)
+ int maxWordLength, int maxWords, int maxAlternatives, int skipPos,
+ int *nextLetters, int nextLettersSize)
{
int suggWords;
mFrequencies = frequencies;
@@ -61,6 +62,8 @@ int Dictionary::getSuggestions(int *codes, int codesSize, unsigned short *outWor
mMaxWords = maxWords;
mSkipPos = skipPos;
mMaxEditDistance = mInputLength < 5 ? 2 : mInputLength / 2;
+ mNextLettersFrequencies = nextLetters;
+ mNextLettersSize = nextLettersSize;
getWordsRec(0, 0, mInputLength * 3, false, 1, 0, 0);
@@ -68,9 +71,27 @@ int Dictionary::getSuggestions(int *codes, int codesSize, unsigned short *outWor
suggWords = 0;
while (suggWords < mMaxWords && mFrequencies[suggWords] > 0) suggWords++;
if (DEBUG_DICT) LOGI("Returning %d words", suggWords);
+
+ if (DEBUG_DICT) {
+ LOGI("Next letters: ");
+ for (int k = 0; k < nextLettersSize; k++) {
+ if (mNextLettersFrequencies[k] > 0) {
+ LOGI("%c = %d,", k, mNextLettersFrequencies[k]);
+ }
+ }
+ LOGI("\n");
+ }
return suggWords;
}
+void
+Dictionary::registerNextLetter(unsigned short c)
+{
+ if (c < mNextLettersSize) {
+ mNextLettersFrequencies[c]++;
+ }
+}
+
unsigned short
Dictionary::getChar(int *pos)
{
@@ -210,6 +231,9 @@ Dictionary::getWordsRec(int pos, int depth, int maxDepth, bool completion, int s
mWord[depth] = c;
if (terminal) {
addWord(mWord, depth + 1, freq * snr);
+ if (depth >= mInputLength && mSkipPos < 0) {
+ registerNextLetter(mWord[mInputLength]);
+ }
}
if (childrenAddress != 0) {
getWordsRec(childrenAddress, depth + 1, maxDepth,
diff --git a/dictionary/src/dictionary.h b/dictionary/src/dictionary.h
index a12c035c8..3749f3d88 100644
--- a/dictionary/src/dictionary.h
+++ b/dictionary/src/dictionary.h
@@ -32,7 +32,8 @@ class Dictionary {
public:
Dictionary(void *dict, int typedLetterMultipler, int fullWordMultiplier);
int getSuggestions(int *codes, int codesSize, unsigned short *outWords, int *frequencies,
- int maxWordLength, int maxWords, int maxAlternatives, int skipPos);
+ int maxWordLength, int maxWords, int maxAlternatives, int skipPos,
+ int *nextLetters, int nextLettersSize);
bool isValidWord(unsigned short *word, int length);
void setAsset(void *asset) { mAsset = asset; }
void *getAsset() { return mAsset; }
@@ -53,6 +54,7 @@ private:
void getWordsRec(int pos, int depth, int maxDepth, bool completion, int frequency,
int inputIndex, int diffs);
bool isValidWordRec(int pos, unsigned short *word, int offset, int length);
+ void registerNextLetter(unsigned short c);
unsigned char *mDict;
void *mAsset;
@@ -70,6 +72,8 @@ private:
int mFullWordMultiplier;
int mTypedLetterMultiplier;
+ int *mNextLettersFrequencies;
+ int mNextLettersSize;
};
// ----------------------------------------------------------------------------
diff --git a/src/com/android/inputmethod/latin/BinaryDictionary.java b/src/com/android/inputmethod/latin/BinaryDictionary.java
index 68d8b740c..ec467c88d 100644
--- a/src/com/android/inputmethod/latin/BinaryDictionary.java
+++ b/src/com/android/inputmethod/latin/BinaryDictionary.java
@@ -65,7 +65,8 @@ public class BinaryDictionary extends Dictionary {
private native boolean isValidWordNative(int nativeData, char[] word, int wordLength);
private native int getSuggestionsNative(int dict, int[] inputCodes, int codesSize,
char[] outputChars, int[] frequencies,
- int maxWordLength, int maxWords, int maxAlternatives, int skipPos);
+ int maxWordLength, int maxWords, int maxAlternatives, int skipPos,
+ int[] nextLettersFrequencies, int nextLettersSize);
private final void loadDictionary(Context context, int resId) {
AssetManager am = context.getResources().getAssets();
@@ -74,7 +75,8 @@ public class BinaryDictionary extends Dictionary {
}
@Override
- public void getWords(final WordComposer codes, final WordCallback callback) {
+ public void getWords(final WordComposer codes, final WordCallback callback,
+ int[] nextLettersFrequencies) {
final int codesSize = codes.size();
// Wont deal with really long words.
if (codesSize > MAX_WORD_LENGTH - 1) return;
@@ -90,7 +92,9 @@ public class BinaryDictionary extends Dictionary {
int count = getSuggestionsNative(mNativeDict, mInputCodes, codesSize,
mOutputChars, mFrequencies,
- MAX_WORD_LENGTH, MAX_WORDS, MAX_ALTERNATIVES, -1);
+ MAX_WORD_LENGTH, MAX_WORDS, MAX_ALTERNATIVES, -1,
+ nextLettersFrequencies,
+ nextLettersFrequencies != null ? nextLettersFrequencies.length : 0);
// If there aren't sufficient suggestions, search for words by allowing wild cards at
// the different character positions. This feature is not ready for prime-time as we need
@@ -100,7 +104,8 @@ public class BinaryDictionary extends Dictionary {
for (int skip = 0; skip < codesSize; skip++) {
int tempCount = getSuggestionsNative(mNativeDict, mInputCodes, codesSize,
mOutputChars, mFrequencies,
- MAX_WORD_LENGTH, MAX_WORDS, MAX_ALTERNATIVES, skip);
+ MAX_WORD_LENGTH, MAX_WORDS, MAX_ALTERNATIVES, skip,
+ null, 0);
count = Math.max(count, tempCount);
if (tempCount > 0) break;
}
diff --git a/src/com/android/inputmethod/latin/ContactsDictionary.java b/src/com/android/inputmethod/latin/ContactsDictionary.java
index fd7ba55fc..f53ebf3f5 100644
--- a/src/com/android/inputmethod/latin/ContactsDictionary.java
+++ b/src/com/android/inputmethod/latin/ContactsDictionary.java
@@ -84,14 +84,15 @@ public class ContactsDictionary extends ExpandableDictionary {
}
@Override
- public synchronized void getWords(final WordComposer codes, final WordCallback callback) {
+ public synchronized void getWords(final WordComposer codes, final WordCallback callback,
+ int[] nextLettersFrequencies) {
synchronized (mUpdatingLock) {
// If we need to update, start off a background task
if (mRequiresReload) loadDictionaryAsyncLocked();
// Currently updating contacts, don't return any results.
if (mUpdatingContacts) return;
}
- super.getWords(codes, callback);
+ super.getWords(codes, callback, nextLettersFrequencies);
}
@Override
diff --git a/src/com/android/inputmethod/latin/Dictionary.java b/src/com/android/inputmethod/latin/Dictionary.java
index 6c1c856e7..b656d04dc 100644
--- a/src/com/android/inputmethod/latin/Dictionary.java
+++ b/src/com/android/inputmethod/latin/Dictionary.java
@@ -55,9 +55,14 @@ abstract public class Dictionary {
* words are added through the callback object.
* @param composer the key sequence to match
* @param callback the callback object to send matched words to as possible candidates
+ * @param nextLettersFrequencies array of frequencies of next letters that could follow the
+ * word so far. For instance, "bracke" can be followed by "t", so array['t'] will have
+ * a non-zero value on returning from this method.
+ * Pass in null if you don't want the dictionary to look up next letters.
* @see WordCallback#addWord(char[], int, int)
*/
- abstract public void getWords(final WordComposer composer, final WordCallback callback);
+ abstract public void getWords(final WordComposer composer, final WordCallback callback,
+ int[] nextLettersFrequencies);
/**
* Checks if the given word occurs in the dictionary
diff --git a/src/com/android/inputmethod/latin/ExpandableDictionary.java b/src/com/android/inputmethod/latin/ExpandableDictionary.java
index 1589168ee..648f577ca 100644
--- a/src/com/android/inputmethod/latin/ExpandableDictionary.java
+++ b/src/com/android/inputmethod/latin/ExpandableDictionary.java
@@ -27,6 +27,7 @@ public class ExpandableDictionary extends Dictionary {
private char[] mWordBuilder = new char[MAX_WORD_LENGTH];
private int mMaxDepth;
private int mInputLength;
+ private int[] mNextLettersFrequencies;
public static final int MAX_WORD_LENGTH = 32;
private static final char QUOTE = '\'';
@@ -116,8 +117,10 @@ public class ExpandableDictionary extends Dictionary {
}
@Override
- public void getWords(final WordComposer codes, final WordCallback callback) {
+ public void getWords(final WordComposer codes, final WordCallback callback,
+ int[] nextLettersFrequencies) {
mInputLength = codes.size();
+ mNextLettersFrequencies = nextLettersFrequencies;
if (mCodes.length < mInputLength) mCodes = new int[mInputLength][];
// Cache the codes so that we don't have to lookup an array list
for (int i = 0; i < mInputLength; i++) {
@@ -216,6 +219,11 @@ public class ExpandableDictionary extends Dictionary {
if (!callback.addWord(word, 0, depth + 1, freq * snr)) {
return;
}
+ // Add to frequency of next letters for predictive correction
+ if (mNextLettersFrequencies != null && depth >= inputIndex && skipPos < 0
+ && mNextLettersFrequencies.length > word[inputIndex]) {
+ mNextLettersFrequencies[word[inputIndex]]++;
+ }
}
if (children != null) {
getWordsRec(children, codes, word, depth + 1, completion, snr, inputIndex,
diff --git a/src/com/android/inputmethod/latin/LatinIME.java b/src/com/android/inputmethod/latin/LatinIME.java
index 56971a534..470b0048e 100644
--- a/src/com/android/inputmethod/latin/LatinIME.java
+++ b/src/com/android/inputmethod/latin/LatinIME.java
@@ -1340,6 +1340,8 @@ public class LatinIME extends InputMethodService
private void updateSuggestions() {
mSuggestionShouldReplaceCurrentWord = false;
+ ((LatinKeyboard) mInputView.getKeyboard()).setPreferredLetters(null);
+
// Check if we have a suggestion engine attached.
if ((mSuggest == null || !isPredictionOn()) && !mVoiceInputHighlighted) {
return;
@@ -1351,6 +1353,10 @@ public class LatinIME extends InputMethodService
}
List<CharSequence> stringList = mSuggest.getSuggestions(mInputView, mWord, false);
+ int[] nextLettersFrequencies = mSuggest.getNextLettersFrequencies();
+
+ ((LatinKeyboard) mInputView.getKeyboard()).setPreferredLetters(nextLettersFrequencies);
+
boolean correctionAvailable = mSuggest.hasMinimalCorrection();
//|| mCorrectionMode == mSuggest.CORRECTION_FULL;
CharSequence typedWord = mWord.getTypedWord();
diff --git a/src/com/android/inputmethod/latin/LatinKeyboard.java b/src/com/android/inputmethod/latin/LatinKeyboard.java
index 64b4529f3..9b742a5f9 100644
--- a/src/com/android/inputmethod/latin/LatinKeyboard.java
+++ b/src/com/android/inputmethod/latin/LatinKeyboard.java
@@ -35,11 +35,15 @@ import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.inputmethodservice.Keyboard;
import android.text.TextPaint;
+import android.util.Log;
import android.view.ViewConfiguration;
import android.view.inputmethod.EditorInfo;
public class LatinKeyboard extends Keyboard {
+ private static final boolean DEBUG_PREFERRED_LETTER = false;
+ private static final String TAG = "LatinKeyboard";
+
private Drawable mShiftLockIcon;
private Drawable mShiftLockPreviewIcon;
private Drawable mOldShiftIcon;
@@ -69,6 +73,12 @@ public class LatinKeyboard extends Keyboard {
private boolean mCurrentlyInSpace;
private SlidingLocaleDrawable mSlidingLocaleIcon;
private Rect mBounds = new Rect();
+ private int[] mPrefLetterFrequencies;
+ private boolean mPreemptiveCorrection;
+ private int mPrefLetter;
+ private int mPrefLetterX;
+ private int mPrefLetterY;
+ private int mPrefDistance;
private int mExtensionResId;
@@ -79,6 +89,8 @@ public class LatinKeyboard extends Keyboard {
private int mShiftState = SHIFT_OFF;
private static final float SPACEBAR_DRAG_THRESHOLD = 0.8f;
+ private static final float OVERLAP_PERCENTAGE_LOW_PROB = 0.70f;
+ private static final float OVERLAP_PERCENTAGE_HIGH_PROB = 0.85f;
static int sSpacebarVerticalCorrection;
@@ -409,9 +421,18 @@ public class LatinKeyboard extends Keyboard {
return mCurrentlyInSpace;
}
+ void setPreferredLetters(int[] frequencies) {
+ mPrefLetterFrequencies = frequencies;
+ mPrefLetter = 0;
+ }
+
void keyReleased() {
mCurrentlyInSpace = false;
mSpaceDragLastDiff = 0;
+ mPrefLetter = 0;
+ mPrefLetterX = 0;
+ mPrefLetterY = 0;
+ mPrefDistance = Integer.MAX_VALUE;
if (mSpaceKey != null) {
updateLocaleDrag(Integer.MAX_VALUE);
}
@@ -448,6 +469,79 @@ public class LatinKeyboard extends Keyboard {
return insideSpace;
}
}
+ } else if (mPrefLetterFrequencies != null) {
+ // New coordinate? Reset
+ if (mPrefLetterX != x || mPrefLetterY != y) {
+ mPrefLetter = 0;
+ mPrefDistance = Integer.MAX_VALUE;
+ }
+ // Handle preferred next letter
+ final int[] pref = mPrefLetterFrequencies;
+ if (mPrefLetter > 0) {
+ if (DEBUG_PREFERRED_LETTER && mPrefLetter == code
+ && !key.isInsideSuper(x, y)) {
+ Log.d(TAG, "CORRECTED !!!!!!");
+ }
+ return mPrefLetter == code;
+ } else {
+ final boolean inside = key.isInsideSuper(x, y);
+ int[] nearby = getNearestKeys(x, y);
+ List<Key> nearbyKeys = getKeys();
+ if (inside) {
+ // If it's a preferred letter
+ if (inPrefList(code, pref)) {
+ // Check if its frequency is much lower than a nearby key
+ mPrefLetter = code;
+ mPrefLetterX = x;
+ mPrefLetterY = y;
+ for (int i = 0; i < nearby.length; i++) {
+ Key k = nearbyKeys.get(nearby[i]);
+ if (k != key && inPrefList(k.codes[0], pref)) {
+ final int dist = distanceFrom(k, x, y);
+ if (dist < (int) (k.width * OVERLAP_PERCENTAGE_LOW_PROB) &&
+ (pref[k.codes[0]] > pref[mPrefLetter] * 3)) {
+ mPrefLetter = k.codes[0];
+ mPrefDistance = dist;
+ if (DEBUG_PREFERRED_LETTER) {
+ Log.d(TAG, "CORRECTED ALTHOUGH PREFERRED !!!!!!");
+ }
+ break;
+ }
+ }
+ }
+
+ return mPrefLetter == code;
+ }
+ }
+
+ // Get the surrounding keys and intersect with the preferred list
+ // For all in the intersection
+ // if distance from touch point is within a reasonable distance
+ // make this the pref letter
+ // If no pref letter
+ // return inside;
+ // else return thiskey == prefletter;
+
+ for (int i = 0; i < nearby.length; i++) {
+ Key k = nearbyKeys.get(nearby[i]);
+ if (inPrefList(k.codes[0], pref)) {
+ final int dist = distanceFrom(k, x, y);
+ if (dist < (int) (k.width * OVERLAP_PERCENTAGE_HIGH_PROB)
+ && dist < mPrefDistance) {
+ mPrefLetter = k.codes[0];
+ mPrefLetterX = x;
+ mPrefLetterY = y;
+ mPrefDistance = dist;
+ }
+ }
+ }
+ // Didn't find any
+ if (mPrefLetter == 0) {
+ return inside;
+ } else {
+ return mPrefLetter == code;
+ }
+ }
}
// Lock into the spacebar
@@ -456,6 +550,19 @@ public class LatinKeyboard extends Keyboard {
return key.isInsideSuper(x, y);
}
+ private boolean inPrefList(int code, int[] pref) {
+ if (code < pref.length && code >= 0) return pref[code] > 0;
+ return false;
+ }
+
+ private int distanceFrom(Key k, int x, int y) {
+ if (y > k.y && y < k.y + k.height) {
+ return Math.abs(k.x + k.width / 2 - x);
+ } else {
+ return Integer.MAX_VALUE;
+ }
+ }
+
@Override
public int[] getNearestKeys(int x, int y) {
if (mCurrentlyInSpace) {
@@ -512,7 +619,8 @@ public class LatinKeyboard extends Keyboard {
*/
@Override
public boolean isInside(int x, int y) {
- return LatinKeyboard.this.isInside(this, x, y);
+ boolean result = LatinKeyboard.this.isInside(this, x, y);
+ return result;
}
boolean isInsideSuper(int x, int y) {
diff --git a/src/com/android/inputmethod/latin/LatinKeyboardView.java b/src/com/android/inputmethod/latin/LatinKeyboardView.java
index 05f8aff36..bdac4a5b5 100644
--- a/src/com/android/inputmethod/latin/LatinKeyboardView.java
+++ b/src/com/android/inputmethod/latin/LatinKeyboardView.java
@@ -20,6 +20,7 @@ import java.util.List;
import android.content.Context;
import android.graphics.Canvas;
+import android.graphics.Paint;
import android.inputmethodservice.Keyboard;
import android.inputmethodservice.KeyboardView;
import android.inputmethodservice.Keyboard.Key;
@@ -80,6 +81,11 @@ public class LatinKeyboardView extends KeyboardView {
@Override
public boolean onTouchEvent(MotionEvent me) {
LatinKeyboard keyboard = (LatinKeyboard) getKeyboard();
+ if (DEBUG_LINE) {
+ mLastX = (int) me.getX();
+ mLastY = (int) me.getY();
+ invalidate();
+ }
// Reset any bounding box controls in the keyboard
if (me.getAction() == MotionEvent.ACTION_DOWN) {
keyboard.keyReleased();
@@ -203,6 +209,7 @@ public class LatinKeyboardView extends KeyboardView {
/**************************** INSTRUMENTATION *******************************/
static final boolean DEBUG_AUTO_PLAY = false;
+ static final boolean DEBUG_LINE = false;
private static final int MSG_TOUCH_DOWN = 1;
private static final int MSG_TOUCH_UP = 2;
@@ -213,6 +220,9 @@ public class LatinKeyboardView extends KeyboardView {
private boolean mDownDelivered;
private Key[] mAsciiKeys = new Key[256];
private boolean mPlaying;
+ private int mLastX;
+ private int mLastY;
+ private Paint mPaint;
@Override
public void setKeyboard(Keyboard k) {
@@ -309,5 +319,14 @@ public class LatinKeyboardView extends KeyboardView {
mHandler2.sendEmptyMessageDelayed(MSG_TOUCH_DOWN, 20);
}
}
+ if (DEBUG_LINE) {
+ if (mPaint == null) {
+ mPaint = new Paint();
+ mPaint.setColor(0x80FFFFFF);
+ mPaint.setAntiAlias(false);
+ }
+ c.drawLine(mLastX, 0, mLastX, getHeight(), mPaint);
+ c.drawLine(0, mLastY, getWidth(), mLastY, mPaint);
+ }
}
}
diff --git a/src/com/android/inputmethod/latin/Suggest.java b/src/com/android/inputmethod/latin/Suggest.java
index c3fe99635..5833c02a5 100755
--- a/src/com/android/inputmethod/latin/Suggest.java
+++ b/src/com/android/inputmethod/latin/Suggest.java
@@ -52,6 +52,12 @@ public class Suggest implements Dictionary.WordCallback {
private int mPrefMaxSuggestions = 12;
private int[] mPriorities = new int[mPrefMaxSuggestions];
+ // Handle predictive correction for only the first 1280 characters for performance reasons
+ // If we support scripts that need latin characters beyond that, we should probably use some
+ // kind of a sparse array or language specific list with a mapping lookup table.
+ // 1280 is the size of the BASE_CHARS array in ExpandableDictionary, which is a basic set of
+ // latin characters.
+ private int[] mNextLettersFrequencies = new int[1280];
private ArrayList<CharSequence> mSuggestions = new ArrayList<CharSequence>();
private ArrayList<CharSequence> mStringPool = new ArrayList<CharSequence>();
private boolean mHaveCorrection;
@@ -162,7 +168,8 @@ public class Suggest implements Dictionary.WordCallback {
mCapitalize = wordComposer.isCapitalized();
collectGarbage();
Arrays.fill(mPriorities, 0);
-
+ Arrays.fill(mNextLettersFrequencies, 0);
+
// Save a lowercase version of the original word
mOriginalWord = wordComposer.getTypedWord();
if (mOriginalWord != null) {
@@ -175,17 +182,17 @@ public class Suggest implements Dictionary.WordCallback {
if (wordComposer.size() > 1) {
if (mUserDictionary != null || mContactsDictionary != null) {
if (mUserDictionary != null) {
- mUserDictionary.getWords(wordComposer, this);
+ mUserDictionary.getWords(wordComposer, this, mNextLettersFrequencies);
}
if (mContactsDictionary != null) {
- mContactsDictionary.getWords(wordComposer, this);
+ mContactsDictionary.getWords(wordComposer, this, mNextLettersFrequencies);
}
if (mSuggestions.size() > 0 && isValidWord(mOriginalWord)) {
mHaveCorrection = true;
}
}
- mMainDict.getWords(wordComposer, this);
+ mMainDict.getWords(wordComposer, this, mNextLettersFrequencies);
if (mCorrectionMode == CORRECTION_FULL && mSuggestions.size() > 0) {
mHaveCorrection = true;
}
@@ -229,6 +236,10 @@ public class Suggest implements Dictionary.WordCallback {
return mSuggestions;
}
+ public int[] getNextLettersFrequencies() {
+ return mNextLettersFrequencies;
+ }
+
private void removeDupes() {
final ArrayList<CharSequence> suggestions = mSuggestions;
if (suggestions.size() < 2) return;
diff --git a/src/com/android/inputmethod/latin/UserDictionary.java b/src/com/android/inputmethod/latin/UserDictionary.java
index 2f3447abd..edd82aaa3 100644
--- a/src/com/android/inputmethod/latin/UserDictionary.java
+++ b/src/com/android/inputmethod/latin/UserDictionary.java
@@ -94,9 +94,10 @@ public class UserDictionary extends ExpandableDictionary {
}
@Override
- public synchronized void getWords(final WordComposer codes, final WordCallback callback) {
+ public synchronized void getWords(final WordComposer codes, final WordCallback callback,
+ int[] nextLettersFrequencies) {
if (mRequiresReload) loadDictionary();
- super.getWords(codes, callback);
+ super.getWords(codes, callback, nextLettersFrequencies);
}
@Override