diff options
6 files changed, 40 insertions, 55 deletions
diff --git a/java/src/com/android/inputmethod/latin/BinaryDictionary.java b/java/src/com/android/inputmethod/latin/BinaryDictionary.java index 323d0c8a3..0aa34e82e 100644 --- a/java/src/com/android/inputmethod/latin/BinaryDictionary.java +++ b/java/src/com/android/inputmethod/latin/BinaryDictionary.java @@ -249,18 +249,8 @@ public final class BinaryDictionary extends Dictionary { final boolean isGesture = composer.isBatchMode(); if (composerSize <= 1 || !isGesture) { if (composerSize > MAX_WORD_LENGTH - 1) return null; - final CharSequence typedWord = composer.getTypedWord(); - final int charCount = typedWord.length(); - int typedWordCharIndex = 0; - int inputCodePointIndex = 0; - while (typedWordCharIndex < charCount) { - final int codePoint = Character.codePointAt(typedWord, typedWordCharIndex); - mInputCodePoints[inputCodePointIndex] = codePoint; - typedWordCharIndex += Character.charCount(codePoint); - inputCodePointIndex += 1; - if (inputCodePointIndex >= MAX_WORD_LENGTH) { - break; - } + for (int i = 0; i < composerSize; i++) { + mInputCodePoints[i] = composer.getCodeAt(i); } } diff --git a/java/src/com/android/inputmethod/latin/LastComposedWord.java b/java/src/com/android/inputmethod/latin/LastComposedWord.java index a3b030626..2a16ab5ab 100644 --- a/java/src/com/android/inputmethod/latin/LastComposedWord.java +++ b/java/src/com/android/inputmethod/latin/LastComposedWord.java @@ -44,6 +44,7 @@ public final class LastComposedWord { public static final String NOT_A_SEPARATOR = ""; + public final int[] mPrimaryKeyCodes; public final ArrayList<Event> mEvents; public final String mTypedWord; public final CharSequence mCommittedWord; @@ -56,15 +57,16 @@ public final class LastComposedWord { private boolean mActive; public static final LastComposedWord NOT_A_COMPOSED_WORD = - new LastComposedWord(new ArrayList<Event>(), null, "", "", - NOT_A_SEPARATOR, null, WordComposer.CAPS_MODE_OFF); + new LastComposedWord(null, new ArrayList<Event>(), null, "", "", + NOT_A_SEPARATOR, null, WordComposer.CAPS_MODE_OFF); // Warning: this is using the passed objects as is and fully expects them to be // immutable. Do not fiddle with their contents after you passed them to this constructor. - public LastComposedWord(final ArrayList<Event> events, + public LastComposedWord(final int[] primaryKeyCodes, final ArrayList<Event> events, final InputPointers inputPointers, final String typedWord, final CharSequence committedWord, final String separatorString, final String prevWord, final int capitalizedMode) { + mPrimaryKeyCodes = primaryKeyCodes; if (inputPointers != null) { mInputPointers.copy(inputPointers); } diff --git a/java/src/com/android/inputmethod/latin/WordComposer.java b/java/src/com/android/inputmethod/latin/WordComposer.java index 4638c8a8b..a955f375b 100644 --- a/java/src/com/android/inputmethod/latin/WordComposer.java +++ b/java/src/com/android/inputmethod/latin/WordComposer.java @@ -43,6 +43,11 @@ public final class WordComposer { private CombinerChain mCombinerChain; + // An array of code points representing the characters typed so far. + // The array is limited to MAX_WORD_LENGTH code points, but mTypedWord extends past that + // and mCodePointSize can go past that. If mCodePointSize is greater than MAX_WORD_LENGTH, + // this just does not contain the associated code points past MAX_WORD_LENGTH. + private int[] mPrimaryKeyCodes; // The list of events that served to compose this string. private final ArrayList<Event> mEvents; private final InputPointers mInputPointers = new InputPointers(MAX_WORD_LENGTH); @@ -86,6 +91,7 @@ public final class WordComposer { public WordComposer() { mCombinerChain = new CombinerChain(); + mPrimaryKeyCodes = new int[MAX_WORD_LENGTH]; mEvents = CollectionUtils.newArrayList(); mTypedWord = new StringBuilder(MAX_WORD_LENGTH); mAutoCorrection = null; @@ -100,6 +106,7 @@ public final class WordComposer { public WordComposer(final WordComposer source) { mCombinerChain = source.mCombinerChain; + mPrimaryKeyCodes = Arrays.copyOf(source.mPrimaryKeyCodes, source.mPrimaryKeyCodes.length); mEvents = new ArrayList<Event>(source.mEvents); mTypedWord = new StringBuilder(source.mTypedWord); mInputPointers.copy(source.mInputPointers); @@ -152,6 +159,14 @@ public final class WordComposer { return size() > 0; } + // TODO: make sure that the index should not exceed MAX_WORD_LENGTH + public int getCodeAt(int index) { + if (index >= MAX_WORD_LENGTH) { + return -1; + } + return mPrimaryKeyCodes[index]; + } + public InputPointers getInputPointers() { return mInputPointers; } @@ -180,6 +195,8 @@ public final class WordComposer { refreshSize(); mCursorPositionWithinWord = mCodePointSize; if (newIndex < MAX_WORD_LENGTH) { + mPrimaryKeyCodes[newIndex] = primaryCode >= Constants.CODE_SPACE + ? Character.toLowerCase(primaryCode) : primaryCode; // In the batch input mode, the {@code mInputPointers} holds batch input points and // shouldn't be overridden by the "typed key" coordinates // (See {@link #setBatchInputWord}). @@ -227,7 +244,15 @@ public final class WordComposer { mCombinerChain.reset(); int actualMoveAmountWithinWord = 0; int cursorPos = mCursorPositionWithinWord; - final int[] codePoints = StringUtils.toCodePointArray(mTypedWord.toString()); + final int[] codePoints; + if (mCodePointSize >= MAX_WORD_LENGTH) { + // If we have more than MAX_WORD_LENGTH characters, we don't have everything inside + // mPrimaryKeyCodes. This should be rare enough that we can afford to just compute + // the array on the fly when this happens. + codePoints = StringUtils.toCodePointArray(mTypedWord.toString()); + } else { + codePoints = mPrimaryKeyCodes; + } if (expectedMoveAmount >= 0) { // Moving the cursor forward for the expected amount or until the end of the word has // been reached, whichever comes first. @@ -426,7 +451,9 @@ public final class WordComposer { // Note: currently, we come here whenever we commit a word. If it's a MANUAL_PICK // or a DECIDED_WORD we may cancel the commit later; otherwise, we should deactivate // the last composed word to ensure this does not happen. - final LastComposedWord lastComposedWord = new LastComposedWord(mEvents, + final int[] primaryKeyCodes = mPrimaryKeyCodes; + mPrimaryKeyCodes = new int[MAX_WORD_LENGTH]; + final LastComposedWord lastComposedWord = new LastComposedWord(primaryKeyCodes, mEvents, mInputPointers, mTypedWord.toString(), committedWord, separatorString, prevWord, mCapitalizedMode); mInputPointers.reset(); @@ -462,6 +489,7 @@ public final class WordComposer { public void resumeSuggestionOnLastComposedWord(final LastComposedWord lastComposedWord, final String previousWord) { + mPrimaryKeyCodes = lastComposedWord.mPrimaryKeyCodes; mEvents.clear(); Collections.copy(mEvents, lastComposedWord.mEvents); mInputPointers.set(lastComposedWord.mInputPointers); diff --git a/native/jni/src/suggest/core/dicnode/dic_node_utils.cpp b/native/jni/src/suggest/core/dicnode/dic_node_utils.cpp index 48752f2cd..2d02a7d9c 100644 --- a/native/jni/src/suggest/core/dicnode/dic_node_utils.cpp +++ b/native/jni/src/suggest/core/dicnode/dic_node_utils.cpp @@ -16,8 +16,6 @@ #include "suggest/core/dicnode/dic_node_utils.h" -#include <cstring> - #include "suggest/core/dicnode/dic_node.h" #include "suggest/core/dicnode/dic_node_vector.h" #include "suggest/core/dictionary/multi_bigram_map.h" @@ -103,34 +101,4 @@ namespace latinime { NOT_A_PROBABILITY); } -//////////////// -// Char utils // -//////////////// - -// TODO: Move to char_utils? -/* static */ int DicNodeUtils::appendTwoWords(const int *const src0, const int16_t length0, - const int *const src1, const int16_t length1, int *const dest) { - int actualLength0 = 0; - for (int i = 0; i < length0; ++i) { - if (src0[i] == 0) { - break; - } - actualLength0 = i + 1; - } - actualLength0 = std::min(actualLength0, MAX_WORD_LENGTH); - memmove(dest, src0, actualLength0 * sizeof(dest[0])); - if (!src1 || length1 == 0) { - return actualLength0; - } - int actualLength1 = 0; - for (int i = 0; i < length1; ++i) { - if (src1[i] == 0) { - break; - } - actualLength1 = i + 1; - } - actualLength1 = std::min(actualLength1, MAX_WORD_LENGTH - actualLength0); - memmove(&dest[actualLength0], src1, actualLength1 * sizeof(dest[0])); - return actualLength0 + actualLength1; -} } // namespace latinime diff --git a/native/jni/src/suggest/core/dicnode/dic_node_utils.h b/native/jni/src/suggest/core/dicnode/dic_node_utils.h index 3f1514a52..4c0f1f15d 100644 --- a/native/jni/src/suggest/core/dicnode/dic_node_utils.h +++ b/native/jni/src/suggest/core/dicnode/dic_node_utils.h @@ -17,8 +17,6 @@ #ifndef LATINIME_DIC_NODE_UTILS_H #define LATINIME_DIC_NODE_UTILS_H -#include <stdint.h> - #include "defines.h" namespace latinime { @@ -30,8 +28,6 @@ class MultiBigramMap; class DicNodeUtils { public: - static int appendTwoWords(const int *src0, const int16_t length0, const int *src1, - const int16_t length1, int *const dest); static void initAsRoot( const DictionaryStructureWithBufferPolicy *const dictionaryStructurePolicy, const int prevWordPtNodePos, DicNode *const newRootDicNode); diff --git a/native/jni/src/suggest/core/result/suggestions_output_utils.cpp b/native/jni/src/suggest/core/result/suggestions_output_utils.cpp index 19912f2ac..a27631510 100644 --- a/native/jni/src/suggest/core/result/suggestions_output_utils.cpp +++ b/native/jni/src/suggest/core/result/suggestions_output_utils.cpp @@ -254,8 +254,9 @@ const int SuggestionsOutputUtils::MIN_LEN_FOR_MULTI_WORD_AUTOCORRECT = 16; outputScores[outputWordIndex] = shortcutScore; outputScores[outputWordIndex] = std::max(S_INT_MIN + 1, shortcutScore) - 1; const int startIndex2 = outputWordIndex * MAX_WORD_LENGTH; - DicNodeUtils::appendTwoWords(0, 0, shortcutTarget, shortcutTargetStringLength, - &outputCodePoints[startIndex2]); + // Copy shortcut target code points to the output buffer. + memmove(&outputCodePoints[startIndex2], shortcutTarget, + shortcutTargetStringLength * sizeof(shortcutTarget[0])); ++outputWordIndex; } return outputWordIndex; |