diff options
-rw-r--r-- | java/src/com/android/inputmethod/latin/LatinIME.java | 10 | ||||
-rw-r--r-- | java/src/com/android/inputmethod/latin/TextEntryState.java | 2 | ||||
-rw-r--r-- | native/src/unigram_dictionary.cpp | 180 | ||||
-rw-r--r-- | native/src/unigram_dictionary.h | 46 |
4 files changed, 97 insertions, 141 deletions
diff --git a/java/src/com/android/inputmethod/latin/LatinIME.java b/java/src/com/android/inputmethod/latin/LatinIME.java index 874d77f19..a83aca0a2 100644 --- a/java/src/com/android/inputmethod/latin/LatinIME.java +++ b/java/src/com/android/inputmethod/latin/LatinIME.java @@ -1181,7 +1181,7 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar mVoiceProxy.handleBackspace(); - boolean deleteChar = false; + final boolean deleteChar = !mHasUncommittedTypedChars; if (mHasUncommittedTypedChars) { final int length = mComposing.length(); if (length > 0) { @@ -1202,8 +1202,6 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar } else { ic.deleteSurroundingText(1, 0); } - } else { - deleteChar = true; } mHandler.postUpdateShiftKeyState(); @@ -1231,7 +1229,7 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar // different behavior only in the case of picking the first // suggestion (typed word). It's intentional to have made this // inconsistent with backspacing after selecting other suggestions. - revertLastWord(deleteChar); + revertLastWord(true /* deleteChar */); } else { sendDownUpKeyEvents(KeyEvent.KEYCODE_DEL); if (mDeleteCount > DELETE_ACCELERATE_AT) { @@ -1799,7 +1797,7 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar return TextUtils.equals(text, beforeText); } - public void revertLastWord(boolean deleteChar) { + private void revertLastWord(boolean deleteChar) { final int length = mComposing.length(); if (!mHasUncommittedTypedChars && length > 0) { final InputConnection ic = getCurrentInputConnection(); @@ -1837,7 +1835,7 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar } } - public boolean revertDoubleSpace() { + private boolean revertDoubleSpace() { mHandler.cancelDoubleSpacesTimer(); final InputConnection ic = getCurrentInputConnection(); // Here we test whether we indeed have a period and a space before us. This should not diff --git a/java/src/com/android/inputmethod/latin/TextEntryState.java b/java/src/com/android/inputmethod/latin/TextEntryState.java index de13f3ae4..b6e261114 100644 --- a/java/src/com/android/inputmethod/latin/TextEntryState.java +++ b/java/src/com/android/inputmethod/latin/TextEntryState.java @@ -144,7 +144,7 @@ public class TextEntryState { break; case UNDO_COMMIT: if (isSpace || isSeparator) { - setState(ACCEPTED_DEFAULT); + setState(START); } else { setState(IN_WORD); } diff --git a/native/src/unigram_dictionary.cpp b/native/src/unigram_dictionary.cpp index e3296f12a..290e9f997 100644 --- a/native/src/unigram_dictionary.cpp +++ b/native/src/unigram_dictionary.cpp @@ -153,6 +153,13 @@ int UnigramDictionary::getSuggestions(const ProximityInfo *proximityInfo, const if (DEBUG_DICT) { LOGI("Returning %d words", suggestedWordsCount); + /// Print the returned words + for (int j = 0; j < suggestedWordsCount; ++j) { + short unsigned int* w = mOutputChars + j * MAX_WORD_LENGTH; + char s[MAX_WORD_LENGTH]; + for (int i = 0; i <= MAX_WORD_LENGTH; i++) s[i] = w[i]; + LOGI("%s %i", s, mFrequencies[j]); + } LOGI("Next letters: "); for (int k = 0; k < NEXT_LETTERS_SIZE; k++) { if (mNextLettersFrequency[k] > 0) { @@ -322,16 +329,6 @@ bool UnigramDictionary::addWord(unsigned short *word, int length, int frequency) return false; } -inline void UnigramDictionary::addWordAlternatesSpellings(const uint8_t* const root, int pos, - int depth, int finalFreq) { - // TODO: actually add alternates when the format supports it. -} - -static inline bool hasAlternateSpellings(uint8_t flags) { - // TODO: when the format supports it, return the actual value. - return false; -} - static inline unsigned short toBaseLowerCase(unsigned short c) { if (c < sizeof(BASE_CHARS) / sizeof(BASE_CHARS[0])) { c = BASE_CHARS[c]; @@ -372,7 +369,7 @@ void UnigramDictionary::getSuggestionCandidates(const int skipPos, assert(missingPos < mInputLength); } int rootPosition = ROOT_POS; - // Get the number of child of root, then increment the position + // Get the number of children of root, then increment the position int childCount = Dictionary::getCount(DICT_ROOT, &rootPosition); int depth = 0; @@ -657,22 +654,19 @@ inline UnigramDictionary::ProximityType UnigramDictionary::getMatchedProximityId } inline void UnigramDictionary::onTerminal(unsigned short int* word, const int depth, - const uint8_t* const root, const uint8_t flags, int pos, + const uint8_t* const root, const uint8_t flags, const int pos, const int inputIndex, const int matchWeight, const int skipPos, const int excessivePos, const int transposedPos, const int freq, const bool sameLength, int* nextLetters, const int nextLettersSize) { const bool isSameAsTyped = sameLength ? sameAsTyped(word, depth + 1) : false; - const bool hasAlternates = hasAlternateSpellings(flags); - if (isSameAsTyped && !hasAlternates) return; + if (isSameAsTyped) return; if (depth >= MIN_SUGGEST_DEPTH) { const int finalFreq = calculateFinalFreq(inputIndex, depth, matchWeight, skipPos, excessivePos, transposedPos, freq, sameLength); if (!isSameAsTyped) addWord(word, depth + 1, finalFreq); - if (hasAlternates) - addWordAlternatesSpellings(DICT_ROOT, pos, flags, finalFreq); } if (sameLength && depth >= mInputLength && skipPos < 0) { @@ -680,6 +674,47 @@ inline void UnigramDictionary::onTerminal(unsigned short int* word, const int de } } +bool UnigramDictionary::getSplitTwoWordsSuggestion(const int inputLength, + const int firstWordStartPos, const int firstWordLength, const int secondWordStartPos, + const int secondWordLength, const bool isSpaceProximity) { + if (inputLength >= MAX_WORD_LENGTH) return false; + if (0 >= firstWordLength || 0 >= secondWordLength || firstWordStartPos >= secondWordStartPos + || firstWordStartPos < 0 || secondWordStartPos + secondWordLength > inputLength) + return false; + const int newWordLength = firstWordLength + secondWordLength + 1; + // Allocating variable length array on stack + unsigned short word[newWordLength]; + const int firstFreq = getMostFrequentWordLike(firstWordStartPos, firstWordLength, mWord); + if (DEBUG_DICT) { + LOGI("First freq: %d", firstFreq); + } + if (firstFreq <= 0) return false; + + for (int i = 0; i < firstWordLength; ++i) { + word[i] = mWord[i]; + } + + const int secondFreq = getMostFrequentWordLike(secondWordStartPos, secondWordLength, mWord); + if (DEBUG_DICT) { + LOGI("Second freq: %d", secondFreq); + } + if (secondFreq <= 0) return false; + + word[firstWordLength] = SPACE; + for (int i = (firstWordLength + 1); i < newWordLength; ++i) { + word[i] = mWord[i - firstWordLength - 1]; + } + + int pairFreq = calcFreqForSplitTwoWords(TYPED_LETTER_MULTIPLIER, firstWordLength, + secondWordLength, firstFreq, secondFreq, isSpaceProximity); + if (DEBUG_DICT) { + LOGI("Split two words: %d, %d, %d, %d, %d", firstFreq, secondFreq, pairFreq, inputLength, + TYPED_LETTER_MULTIPLIER); + } + addWord(word, newWordLength, pairFreq); + return true; +} + #ifndef NEW_DICTIONARY_FORMAT // TODO: Don't forget to bring inline functions back to over where they are used. @@ -725,8 +760,8 @@ void UnigramDictionary::getWordsRec(const int childrenCount, const int pos, cons } } -inline int UnigramDictionary::getBestWordFreq(const int startInputIndex, const int inputLength, - unsigned short *word) { +inline int UnigramDictionary::getMostFrequentWordLike(const int startInputIndex, + const int inputLength, unsigned short *word) { int pos = ROOT_POS; int count = Dictionary::getCount(DICT_ROOT, &pos); int maxFreq = 0; @@ -860,52 +895,10 @@ int UnigramDictionary::getBigramPosition(int pos, unsigned short *word, int offs return NOT_VALID_WORD; } - // The following functions will be modified. -bool UnigramDictionary::getSplitTwoWordsSuggestion(const int inputLength, - const int firstWordStartPos, const int firstWordLength, const int secondWordStartPos, - const int secondWordLength, const bool isSpaceProximity) { - if (inputLength >= MAX_WORD_LENGTH) return false; - if (0 >= firstWordLength || 0 >= secondWordLength || firstWordStartPos >= secondWordStartPos - || firstWordStartPos < 0 || secondWordStartPos + secondWordLength > inputLength) - return false; - const int newWordLength = firstWordLength + secondWordLength + 1; - // Allocating variable length array on stack - unsigned short word[newWordLength]; - const int firstFreq = getBestWordFreq(firstWordStartPos, firstWordLength, mWord); - if (DEBUG_DICT) { - LOGI("First freq: %d", firstFreq); - } - if (firstFreq <= 0) return false; - - for (int i = 0; i < firstWordLength; ++i) { - word[i] = mWord[i]; - } - - const int secondFreq = getBestWordFreq(secondWordStartPos, secondWordLength, mWord); - if (DEBUG_DICT) { - LOGI("Second freq: %d", secondFreq); - } - if (secondFreq <= 0) return false; - - word[firstWordLength] = SPACE; - for (int i = (firstWordLength + 1); i < newWordLength; ++i) { - word[i] = mWord[i - firstWordLength - 1]; - } - - int pairFreq = calcFreqForSplitTwoWords(TYPED_LETTER_MULTIPLIER, firstWordLength, - secondWordLength, firstFreq, secondFreq, isSpaceProximity); - if (DEBUG_DICT) { - LOGI("Split two words: %d, %d, %d, %d, %d", firstFreq, secondFreq, pairFreq, inputLength, - TYPED_LETTER_MULTIPLIER); - } - addWord(word, newWordLength, pairFreq); - return true; -} - -inline bool UnigramDictionary::processCurrentNode(const int pos, const int depth, - const int maxDepth, const bool traverseAllNodes, int matchWeight, int inputIndex, - const int diffs, const int skipPos, const int excessivePos, const int transposedPos, +inline bool UnigramDictionary::processCurrentNode(const int initialPos, const int initialDepth, + const int maxDepth, const bool initialTraverseAllNodes, int matchWeight, int inputIndex, + const int initialDiffs, const int skipPos, const int excessivePos, const int transposedPos, int *nextLetters, const int nextLettersSize, int *newCount, int *newChildPosition, bool *newTraverseAllNodes, int *newMatchRate, int *newInputIndex, int *newDiffs, int *nextSiblingPosition, int *nextOutputIndex) { @@ -922,6 +915,11 @@ inline bool UnigramDictionary::processCurrentNode(const int pos, const int depth int freq; bool isSameAsUserTypedLength = false; + const int pos = initialPos; + const int depth = initialDepth; + const int traverseAllNodes = initialTraverseAllNodes; + const int diffs = initialDiffs; + const uint8_t flags = 0; // No flags for now if (excessivePos == depth && inputIndex < mInputLength - 1) ++inputIndex; @@ -993,53 +991,12 @@ inline bool UnigramDictionary::processCurrentNode(const int pos, const int depth #else // NEW_DICTIONARY_FORMAT -bool UnigramDictionary::getSplitTwoWordsSuggestion(const int inputLength, - const int firstWordStartPos, const int firstWordLength, const int secondWordStartPos, - const int secondWordLength, const bool isSpaceProximity) { - if (inputLength >= MAX_WORD_LENGTH) return false; - if (0 >= firstWordLength || 0 >= secondWordLength || firstWordStartPos >= secondWordStartPos - || firstWordStartPos < 0 || secondWordStartPos + secondWordLength > inputLength) - return false; - const int newWordLength = firstWordLength + secondWordLength + 1; - // Allocating variable length array on stack - unsigned short word[newWordLength]; - const int firstFreq = getBestWordFreq(firstWordStartPos, firstWordLength, mWord); - if (DEBUG_DICT) { - LOGI("First freq: %d", firstFreq); - } - if (firstFreq <= 0) return false; - - for (int i = 0; i < firstWordLength; ++i) { - word[i] = mWord[i]; - } - - const int secondFreq = getBestWordFreq(secondWordStartPos, secondWordLength, mWord); - if (DEBUG_DICT) { - LOGI("Second freq: %d", secondFreq); - } - if (secondFreq <= 0) return false; - - word[firstWordLength] = SPACE; - for (int i = (firstWordLength + 1); i < newWordLength; ++i) { - word[i] = mWord[i - firstWordLength - 1]; - } - - int pairFreq = calcFreqForSplitTwoWords(TYPED_LETTER_MULTIPLIER, firstWordLength, - secondWordLength, firstFreq, secondFreq, isSpaceProximity); - if (DEBUG_DICT) { - LOGI("Split two words: %d, %d, %d, %d, %d", firstFreq, secondFreq, pairFreq, inputLength, - TYPED_LETTER_MULTIPLIER); - } - addWord(word, newWordLength, pairFreq); - return true; -} - -inline bool UnigramDictionary::processCurrentNode(const int pos, const int depth, - const int maxDepth, const bool traverseAllNodes, int matchWeight, int inputIndex, - const int diffs, const int skipPos, const int excessivePos, const int transposedPos, +inline bool UnigramDictionary::processCurrentNode(const int initialPos, const int initialDepth, + const int maxDepth, const bool initialTraverseAllNodes, int matchWeight, int inputIndex, + const int initialDiffs, const int skipPos, const int excessivePos, const int transposedPos, int *nextLetters, const int nextLettersSize, int *newCount, int *newChildPosition, bool *newTraverseAllNodes, int *newMatchRate, int *newInputIndex, int *newDiffs, - int *nextSiblingPosition, int *nextOutputIndex) { + int *nextSiblingPosition, int *newOutputIndex) { if (DEBUG_DICT) { int inputCount = 0; if (skipPos >= 0) ++inputCount; @@ -1053,13 +1010,18 @@ inline bool UnigramDictionary::processCurrentNode(const int pos, const int depth int freq; bool isSameAsUserTypedLength = false; + int pos = initialPos; + int depth = initialDepth; + int traverseAllNodes = initialTraverseAllNodes; + int diffs = initialDiffs; + const uint8_t flags = 0; // No flags for now if (excessivePos == depth && inputIndex < mInputLength - 1) ++inputIndex; *nextSiblingPosition = Dictionary::setDictionaryValues(DICT_ROOT, IS_LATEST_DICT_VERSION, pos, &c, &childPosition, &terminal, &freq); - *nextOutputIndex = depth + 1; + *newOutputIndex = depth + 1; const bool needsToTraverseChildrenNodes = childPosition != 0; diff --git a/native/src/unigram_dictionary.h b/native/src/unigram_dictionary.h index 154ac9b36..789c49596 100644 --- a/native/src/unigram_dictionary.h +++ b/native/src/unigram_dictionary.h @@ -60,31 +60,18 @@ private: void getSuggestionCandidates(const int skipPos, const int excessivePos, const int transposedPos, int *nextLetters, const int nextLettersSize, const int maxDepth); - void getVersionNumber(); - bool checkIfDictVersionIsLatest(); - int getAddress(int *pos); - int getFreq(int *pos); bool sameAsTyped(const unsigned short *word, int length) const; bool addWord(unsigned short *word, int length, int frequency); - void addWordAlternatesSpellings(const uint8_t* const root, int pos, int depth, int finalFreq); - void getWordsRec(const int childrenCount, const int pos, const int depth, const int maxDepth, - const bool traverseAllNodes, const int snr, const int inputIndex, const int diffs, - const int skipPos, const int excessivePos, const int transposedPos, int *nextLetters, - const int nextLettersSize); bool getSplitTwoWordsSuggestion(const int inputLength, const int firstWordStartPos, const int firstWordLength, const int secondWordStartPos, const int secondWordLength, const bool isSpaceProximity); bool getMissingSpaceWords(const int inputLength, const int missingSpacePos); bool getMistypedSpaceWords(const int inputLength, const int spaceProximityPos); - // Keep getWordsOld for comparing performance between getWords and getWordsOld - void getWordsOld(const int initialPos, const int inputLength, const int skipPos, - const int excessivePos, const int transposedPos, int *nextLetters, - const int nextLettersSize); int calculateFinalFreq(const int inputIndex, const int depth, const int snr, const int skipPos, const int excessivePos, const int transposedPos, const int freq, const bool sameLength) const; void onTerminal(unsigned short int* word, const int depth, - const uint8_t* const root, const uint8_t flags, int pos, + const uint8_t* const root, const uint8_t flags, const int pos, const int inputIndex, const int matchWeight, const int skipPos, const int excessivePos, const int transposedPos, const int freq, const bool sameLength, int *nextLetters, const int nextLettersSize); @@ -93,21 +80,30 @@ private: ProximityType getMatchedProximityId(const int *currentChars, const unsigned short c, const int skipPos, const int excessivePos, const int transposedPos); // Process a node by considering proximity, missing and excessive character - bool processCurrentNode(const int pos, const int depth, - const int maxDepth, const bool traverseAllNodes, const int snr, int inputIndex, - const int diffs, const int skipPos, const int excessivePos, const int transposedPos, - int *nextLetters, const int nextLettersSize, int *newCount, int *newChildPosition, - bool *newTraverseAllNodes, int *newSnr, int*newInputIndex, int *newDiffs, - int *nextSiblingPosition, int *nextOutputIndex); - int getBestWordFreq(const int startInputIndex, const int inputLength, unsigned short *word); - // Process a node by considering missing space - bool processCurrentNodeForExactMatch(const int firstChildPos, - const int startInputIndex, const int depth, unsigned short *word, - int *newChildPosition, int *newCount, bool *newTerminal, int *newFreq, int *siblingPos); + bool processCurrentNode(const int initialPos, const int initialDepth, + const int maxDepth, const bool initialTraverseAllNodes, const int snr, int inputIndex, + const int initialDiffs, const int skipPos, const int excessivePos, + const int transposedPos, int *nextLetters, const int nextLettersSize, int *newCount, + int *newChildPosition, bool *newTraverseAllNodes, int *newSnr, int*newInputIndex, + int *newDiffs, int *nextSiblingPosition, int *nextOutputIndex); bool existsAdjacentProximityChars(const int inputIndex, const int inputLength) const; inline const int* getInputCharsAt(const int index) const { return mInputCodes + (index * MAX_PROXIMITY_CHARS); } + int getMostFrequentWordLike(const int startInputIndex, const int inputLength, + unsigned short *word); + void getWordsRec(const int childrenCount, const int pos, const int depth, const int maxDepth, + const bool traverseAllNodes, const int snr, const int inputIndex, const int diffs, + const int skipPos, const int excessivePos, const int transposedPos, int *nextLetters, + const int nextLettersSize); + // Keep getWordsOld for comparing performance between getWords and getWordsOld + void getWordsOld(const int initialPos, const int inputLength, const int skipPos, + const int excessivePos, const int transposedPos, int *nextLetters, + const int nextLettersSize); + // Process a node by considering missing space + bool processCurrentNodeForExactMatch(const int firstChildPos, + const int startInputIndex, const int depth, unsigned short *word, + int *newChildPosition, int *newCount, bool *newTerminal, int *newFreq, int *siblingPos); const uint8_t* const DICT_ROOT; const int MAX_WORD_LENGTH; |