diff options
Diffstat (limited to 'java/src/com/android/inputmethod/latin/BinaryDictionary.java')
-rw-r--r-- | java/src/com/android/inputmethod/latin/BinaryDictionary.java | 141 |
1 files changed, 53 insertions, 88 deletions
diff --git a/java/src/com/android/inputmethod/latin/BinaryDictionary.java b/java/src/com/android/inputmethod/latin/BinaryDictionary.java index d0613bd72..534cffb2d 100644 --- a/java/src/com/android/inputmethod/latin/BinaryDictionary.java +++ b/java/src/com/android/inputmethod/latin/BinaryDictionary.java @@ -20,7 +20,9 @@ import android.content.Context; import android.text.TextUtils; import com.android.inputmethod.keyboard.ProximityInfo; +import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo; +import java.util.ArrayList; import java.util.Arrays; import java.util.Locale; @@ -40,19 +42,20 @@ public class BinaryDictionary extends Dictionary { */ public static final int MAX_WORD_LENGTH = 48; public static final int MAX_WORDS = 18; + public static final int MAX_SPACES = 16; private static final String TAG = "BinaryDictionary"; - private static final int MAX_BIGRAMS = 60; + private static final int MAX_PREDICTIONS = 60; + private static final int MAX_RESULTS = Math.max(MAX_PREDICTIONS, MAX_WORDS); private static final int TYPED_LETTER_MULTIPLIER = 2; - private int mDicTypeId; private long mNativeDict; private final int[] mInputCodes = new int[MAX_WORD_LENGTH]; - private final char[] mOutputChars = new char[MAX_WORD_LENGTH * MAX_WORDS]; - private final char[] mOutputChars_bigrams = new char[MAX_WORD_LENGTH * MAX_BIGRAMS]; - private final int[] mScores = new int[MAX_WORDS]; - private final int[] mBigramScores = new int[MAX_BIGRAMS]; + private final char[] mOutputChars = new char[MAX_WORD_LENGTH * MAX_RESULTS]; + private final int[] mSpaceIndices = new int[MAX_SPACES]; + private final int[] mOutputScores = new int[MAX_RESULTS]; + private final int[] mOutputTypes = new int[MAX_RESULTS]; private final boolean mUseFullEditDistance; @@ -65,14 +68,12 @@ public class BinaryDictionary extends Dictionary { * @param offset the offset of the dictionary data within the file. * @param length the length of the binary data. * @param useFullEditDistance whether to use the full edit distance in suggestions + * @param dictType the dictionary type, as a human-readable string */ public BinaryDictionary(final Context context, final String filename, final long offset, final long length, - final boolean useFullEditDistance, final Locale locale) { - // Note: at the moment a binary dictionary is always of the "main" type. - // Initializing this here will help transitioning out of the scheme where - // the Suggest class knows everything about every single dictionary. - mDicTypeId = Suggest.DIC_MAIN; + final boolean useFullEditDistance, final Locale locale, final String dictType) { + super(dictType); mUseFullEditDistance = useFullEditDistance; loadDictionary(filename, offset, length); } @@ -82,113 +83,77 @@ public class BinaryDictionary extends Dictionary { } private native long openNative(String sourceDir, long dictOffset, long dictSize, - int typedLetterMultiplier, int fullWordMultiplier, int maxWordLength, int maxWords); + int typedLetterMultiplier, int fullWordMultiplier, int maxWordLength, int maxWords, + int maxPredictions); private native void closeNative(long dict); private native int getFrequencyNative(long dict, int[] word, int wordLength); private native boolean isValidBigramNative(long dict, int[] word1, int[] word2); private native int getSuggestionsNative(long dict, long proximityInfo, int[] xCoordinates, - int[] yCoordinates, int[] inputCodes, int codesSize, int[] prevWordForBigrams, - boolean useFullEditDistance, char[] outputChars, int[] scores); - private native int getBigramsNative(long dict, int[] prevWord, int prevWordLength, - int[] inputCodes, int inputCodesLength, char[] outputChars, int[] scores, - int maxWordLength, int maxBigrams); + int[] yCoordinates, int[] times, int[] pointerIds, int[] inputCodes, int codesSize, + int commitPoint, boolean isGesture, + int[] prevWordCodePointArray, boolean useFullEditDistance, char[] outputChars, + int[] outputScores, int[] outputIndices, int[] outputTypes); private static native float calcNormalizedScoreNative( char[] before, int beforeLength, char[] after, int afterLength, int score); private static native int editDistanceNative( char[] before, int beforeLength, char[] after, int afterLength); private final void loadDictionary(String path, long startOffset, long length) { - mNativeDict = openNative(path, startOffset, length, - TYPED_LETTER_MULTIPLIER, FULL_WORD_SCORE_MULTIPLIER, MAX_WORD_LENGTH, MAX_WORDS); + mNativeDict = openNative(path, startOffset, length, TYPED_LETTER_MULTIPLIER, + FULL_WORD_SCORE_MULTIPLIER, MAX_WORD_LENGTH, MAX_WORDS, MAX_PREDICTIONS); } @Override - public void getBigrams(final WordComposer codes, final CharSequence previousWord, - final WordCallback callback) { - if (mNativeDict == 0) return; - - int[] codePoints = StringUtils.toCodePointArray(previousWord.toString()); - Arrays.fill(mOutputChars_bigrams, (char) 0); - Arrays.fill(mBigramScores, 0); - - int codesSize = codes.size(); - Arrays.fill(mInputCodes, -1); - if (codesSize > 0) { - mInputCodes[0] = codes.getCodeAt(0); - } - - int count = getBigramsNative(mNativeDict, codePoints, codePoints.length, mInputCodes, - codesSize, mOutputChars_bigrams, mBigramScores, MAX_WORD_LENGTH, MAX_BIGRAMS); - if (count > MAX_BIGRAMS) { - count = MAX_BIGRAMS; - } - - for (int j = 0; j < count; ++j) { - if (codesSize > 0 && mBigramScores[j] < 1) break; - final int start = j * MAX_WORD_LENGTH; - int len = 0; - while (len < MAX_WORD_LENGTH && mOutputChars_bigrams[start + len] != 0) { - ++len; - } - if (len > 0) { - callback.addWord(mOutputChars_bigrams, start, len, mBigramScores[j], - mDicTypeId, Dictionary.BIGRAM); + public ArrayList<SuggestedWordInfo> getSuggestions(final WordComposer composer, + final CharSequence prevWord, final ProximityInfo proximityInfo) { + if (!isValidDictionary()) return null; + Arrays.fill(mInputCodes, WordComposer.NOT_A_CODE); + Arrays.fill(mOutputChars, (char) 0); + Arrays.fill(mOutputScores, 0); + // TODO: toLowerCase in the native code + final int[] prevWordCodePointArray = (null == prevWord) + ? null : StringUtils.toCodePointArray(prevWord.toString()); + final int composerSize = composer.size(); + + final boolean isGesture = composer.isBatchMode(); + if (composerSize <= 1 || !isGesture) { + if (composerSize > MAX_WORD_LENGTH - 1) return null; + for (int i = 0; i < composerSize; i++) { + mInputCodes[i] = composer.getCodeAt(i); } } - } - - // proximityInfo and/or prevWordForBigrams may not be null. - @Override - public void getWords(final WordComposer codes, final CharSequence prevWordForBigrams, - final WordCallback callback, final ProximityInfo proximityInfo) { - final int count = getSuggestions(codes, prevWordForBigrams, proximityInfo, mOutputChars, - mScores); + final InputPointers ips = composer.getInputPointers(); + final int codesSize = isGesture ? ips.getPointerSize() : composerSize; + // proximityInfo and/or prevWordForBigrams may not be null. + final int tmpCount = getSuggestionsNative(mNativeDict, + proximityInfo.getNativeProximityInfo(), ips.getXCoordinates(), + ips.getYCoordinates(), ips.getTimes(), ips.getPointerIds(), + mInputCodes, codesSize, 0 /* commitPoint */, isGesture, prevWordCodePointArray, + mUseFullEditDistance, mOutputChars, mOutputScores, mSpaceIndices, mOutputTypes); + final int count = Math.min(tmpCount, MAX_PREDICTIONS); + + final ArrayList<SuggestedWordInfo> suggestions = new ArrayList<SuggestedWordInfo>(); for (int j = 0; j < count; ++j) { - if (mScores[j] < 1) break; + if (composerSize > 0 && mOutputScores[j] < 1) break; final int start = j * MAX_WORD_LENGTH; int len = 0; - while (len < MAX_WORD_LENGTH && mOutputChars[start + len] != 0) { + while (len < MAX_WORD_LENGTH && mOutputChars[start + len] != 0) { ++len; } if (len > 0) { - callback.addWord(mOutputChars, start, len, mScores[j], mDicTypeId, - Dictionary.UNIGRAM); + suggestions.add(new SuggestedWordInfo( + new String(mOutputChars, start, len), + mOutputScores[j], SuggestedWordInfo.KIND_CORRECTION, mDictType)); } } + return suggestions; } /* package for test */ boolean isValidDictionary() { return mNativeDict != 0; } - // proximityInfo may not be null. - /* package for test */ int getSuggestions(final WordComposer codes, - final CharSequence prevWordForBigrams, final ProximityInfo proximityInfo, - char[] outputChars, int[] scores) { - if (!isValidDictionary()) return -1; - - final int codesSize = codes.size(); - // Won't deal with really long words. - if (codesSize > MAX_WORD_LENGTH - 1) return -1; - - Arrays.fill(mInputCodes, WordComposer.NOT_A_CODE); - for (int i = 0; i < codesSize; i++) { - mInputCodes[i] = codes.getCodeAt(i); - } - Arrays.fill(outputChars, (char) 0); - Arrays.fill(scores, 0); - - final int[] prevWordCodePointArray = null == prevWordForBigrams - ? null : StringUtils.toCodePointArray(prevWordForBigrams.toString()); - - // TODO: pass the previous word to native code - return getSuggestionsNative( - mNativeDict, proximityInfo.getNativeProximityInfo(), - codes.getXCoordinates(), codes.getYCoordinates(), mInputCodes, codesSize, - prevWordCodePointArray, mUseFullEditDistance, outputChars, scores); - } - public static float calcNormalizedScore(String before, String after, int score) { return calcNormalizedScoreNative(before.toCharArray(), before.length(), after.toCharArray(), after.length(), score); |