diff options
Diffstat (limited to 'native/jni')
-rw-r--r-- | native/jni/src/correction.cpp | 122 | ||||
-rw-r--r-- | native/jni/src/correction.h | 16 | ||||
-rw-r--r-- | native/jni/src/defines.h | 3 | ||||
-rw-r--r-- | native/jni/src/geometry_utils.h | 1 | ||||
-rw-r--r-- | native/jni/src/proximity_info_state.cpp | 129 | ||||
-rw-r--r-- | native/jni/src/proximity_info_state.h | 39 | ||||
-rw-r--r-- | native/jni/src/unigram_dictionary.cpp | 68 | ||||
-rw-r--r-- | native/jni/src/unigram_dictionary.h | 14 |
8 files changed, 252 insertions, 140 deletions
diff --git a/native/jni/src/correction.cpp b/native/jni/src/correction.cpp index 71f8a4fc8..342dec9a3 100644 --- a/native/jni/src/correction.cpp +++ b/native/jni/src/correction.cpp @@ -61,19 +61,19 @@ inline static void dumpEditDistance10ForDebug(int *editDistanceTable, } inline static void calcEditDistanceOneStep(int *editDistanceTable, const unsigned short *input, - const int inputLength, const unsigned short *output, const int outputLength) { + const int inputSize, const unsigned short *output, const int outputLength) { // TODO: Make sure that editDistance[0 ~ MAX_WORD_LENGTH_INTERNAL] is not touched. - // Let dp[i][j] be editDistanceTable[i * (inputLength + 1) + j]. - // Assuming that dp[0][0] ... dp[outputLength - 1][inputLength] are already calculated, - // and calculate dp[ouputLength][0] ... dp[outputLength][inputLength]. - int *const current = editDistanceTable + outputLength * (inputLength + 1); - const int *const prev = editDistanceTable + (outputLength - 1) * (inputLength + 1); + // Let dp[i][j] be editDistanceTable[i * (inputSize + 1) + j]. + // Assuming that dp[0][0] ... dp[outputLength - 1][inputSize] are already calculated, + // and calculate dp[ouputLength][0] ... dp[outputLength][inputSize]. + int *const current = editDistanceTable + outputLength * (inputSize + 1); + const int *const prev = editDistanceTable + (outputLength - 1) * (inputSize + 1); const int *const prevprev = - outputLength >= 2 ? editDistanceTable + (outputLength - 2) * (inputLength + 1) : 0; + outputLength >= 2 ? editDistanceTable + (outputLength - 2) * (inputSize + 1) : 0; current[0] = outputLength; const uint32_t co = toBaseLowerCase(output[outputLength - 1]); const uint32_t prevCO = outputLength >= 2 ? toBaseLowerCase(output[outputLength - 2]) : 0; - for (int i = 1; i <= inputLength; ++i) { + for (int i = 1; i <= inputSize; ++i) { const uint32_t ci = toBaseLowerCase(input[i - 1]); const uint16_t cost = (ci == co) ? 0 : 1; current[i] = min(current[i - 1] + 1, min(prev[i] + 1, prev[i - 1] + cost)); @@ -84,11 +84,11 @@ inline static void calcEditDistanceOneStep(int *editDistanceTable, const unsigne } inline static int getCurrentEditDistance(int *editDistanceTable, const int editDistanceTableWidth, - const int outputLength, const int inputLength) { + const int outputLength, const int inputSize) { if (DEBUG_EDIT_DISTANCE) { - AKLOGI("getCurrentEditDistance %d, %d", inputLength, outputLength); + AKLOGI("getCurrentEditDistance %d, %d", inputSize, outputLength); } - return editDistanceTable[(editDistanceTableWidth + 1) * (outputLength) + inputLength]; + return editDistanceTable[(editDistanceTableWidth + 1) * (outputLength) + inputSize]; } ////////////////////// @@ -109,12 +109,12 @@ void Correction::resetCorrection() { mTotalTraverseCount = 0; } -void Correction::initCorrection(const ProximityInfo *pi, const int inputLength, +void Correction::initCorrection(const ProximityInfo *pi, const int inputSize, const int maxDepth) { mProximityInfo = pi; - mInputLength = inputLength; + mInputSize = inputSize; mMaxDepth = maxDepth; - mMaxEditDistance = mInputLength < 5 ? 2 : mInputLength / 2; + mMaxEditDistance = mInputSize < 5 ? 2 : mInputSize / 2; // TODO: This is not supposed to be required. Check what's going wrong with // editDistance[0 ~ MAX_WORD_LENGTH_INTERNAL] initEditDistance(mEditDistanceTable); @@ -168,22 +168,22 @@ int Correction::getFreqForSplitMultipleWords(const int *freqArray, const int *wo } int Correction::getFinalProbability(const int probability, unsigned short **word, int *wordLength) { - return getFinalProbabilityInternal(probability, word, wordLength, mInputLength); + return getFinalProbabilityInternal(probability, word, wordLength, mInputSize); } int Correction::getFinalProbabilityForSubQueue(const int probability, unsigned short **word, - int *wordLength, const int inputLength) { - return getFinalProbabilityInternal(probability, word, wordLength, inputLength); + int *wordLength, const int inputSize) { + return getFinalProbabilityInternal(probability, word, wordLength, inputSize); } int Correction::getFinalProbabilityInternal(const int probability, unsigned short **word, - int *wordLength, const int inputLength) { + int *wordLength, const int inputSize) { const int outputIndex = mTerminalOutputIndex; const int inputIndex = mTerminalInputIndex; *wordLength = outputIndex + 1; *word = mWord; int finalProbability= Correction::RankingAlgorithm::calculateFinalProbability( - inputIndex, outputIndex, probability, mEditDistanceTable, this, inputLength); + inputIndex, outputIndex, probability, mEditDistanceTable, this, inputSize); return finalProbability; } @@ -270,13 +270,13 @@ bool Correction::needsToPrune() const { // TODO: use edit distance here return mOutputIndex - 1 >= mMaxDepth || mProximityCount > mMaxEditDistance // Allow one char longer word for missing character - || (!mDoAutoCompletion && (mOutputIndex > mInputLength)); + || (!mDoAutoCompletion && (mOutputIndex > mInputSize)); } void Correction::addCharToCurrentWord(const int32_t c) { mWord[mOutputIndex] = c; const unsigned short *primaryInputWord = mProximityInfoState.getPrimaryInputWord(); - calcEditDistanceOneStep(mEditDistanceTable, primaryInputWord, mInputLength, + calcEditDistanceOneStep(mEditDistanceTable, primaryInputWord, mInputSize, mWord, mOutputIndex + 1); } @@ -325,7 +325,7 @@ Correction::CorrectionType Correction::processCharAndCalcState( // Skip checking this node if (mNeedsToTraverseAllNodes || isSingleQuote(c)) { bool incremented = false; - if (mLastCharExceeded && mInputIndex == mInputLength - 1) { + if (mLastCharExceeded && mInputIndex == mInputSize - 1) { // TODO: Do not check the proximity if EditDistance exceeds the threshold const ProximityType matchId = mProximityInfoState.getMatchedProximityId( mInputIndex, c, true, &proximityIndex); @@ -354,7 +354,7 @@ Correction::CorrectionType Correction::processCharAndCalcState( if (mExcessiveCount == 0 && mExcessivePos < mOutputIndex) { mExcessivePos = mOutputIndex; } - if (mExcessivePos < mInputLength - 1) { + if (mExcessivePos < mInputSize - 1) { mExceeding = mExcessivePos == mInputIndex && canTryCorrection; } } @@ -373,7 +373,7 @@ Correction::CorrectionType Correction::processCharAndCalcState( if (mTransposedCount == 0 && mTransposedPos < mOutputIndex) { mTransposedPos = mOutputIndex; } - if (mTransposedPos < mInputLength - 1) { + if (mTransposedPos < mInputSize - 1) { mTransposing = mInputIndex == mTransposedPos && canTryCorrection; } } @@ -392,7 +392,7 @@ Correction::CorrectionType Correction::processCharAndCalcState( } else { --mTransposedCount; if (DEBUG_CORRECTION - && (INPUTLENGTH_FOR_DEBUG <= 0 || INPUTLENGTH_FOR_DEBUG == mInputLength) + && (INPUTLENGTH_FOR_DEBUG <= 0 || INPUTLENGTH_FOR_DEBUG == mInputSize) && (MIN_OUTPUT_INDEX_FOR_DEBUG <= 0 || MIN_OUTPUT_INDEX_FOR_DEBUG < mOutputIndex)) { DUMP_WORD(mWord, mOutputIndex); @@ -423,7 +423,7 @@ Correction::CorrectionType Correction::processCharAndCalcState( && isEquivalentChar(mProximityInfoState.getMatchedProximityId( mInputIndex, mWord[mOutputIndex - 1], false))) { if (DEBUG_CORRECTION - && (INPUTLENGTH_FOR_DEBUG <= 0 || INPUTLENGTH_FOR_DEBUG == mInputLength) + && (INPUTLENGTH_FOR_DEBUG <= 0 || INPUTLENGTH_FOR_DEBUG == mInputSize) && (MIN_OUTPUT_INDEX_FOR_DEBUG <= 0 || MIN_OUTPUT_INDEX_FOR_DEBUG < mOutputIndex)) { AKLOGI("CONVERSION p->e %c", mWord[mOutputIndex - 1]); @@ -453,7 +453,7 @@ Correction::CorrectionType Correction::processCharAndCalcState( // As the current char turned out to be an unrelated char, // we will try other correction-types. Please note that mCorrectionStates[mOutputIndex] // here refers to the previous state. - if (mInputIndex < mInputLength - 1 && mOutputIndex > 0 && mTransposedCount > 0 + if (mInputIndex < mInputSize - 1 && mOutputIndex > 0 && mTransposedCount > 0 && !mCorrectionStates[mOutputIndex].mTransposing && mCorrectionStates[mOutputIndex - 1].mTransposing && isEquivalentChar(mProximityInfoState.getMatchedProximityId( @@ -490,7 +490,7 @@ Correction::CorrectionType Correction::processCharAndCalcState( ++mSkippedCount; --mProximityCount; return processSkipChar(c, isTerminal, false); - } else if (mInputIndex - 1 < mInputLength + } else if (mInputIndex - 1 < mInputSize && mSkippedCount > 0 && mCorrectionStates[mOutputIndex].mSkipping && mCorrectionStates[mOutputIndex].mAdditionalProximityMatching @@ -502,7 +502,7 @@ Correction::CorrectionType Correction::processCharAndCalcState( mProximityMatching = true; ++mProximityCount; mDistances[mOutputIndex] = ADDITIONAL_PROXIMITY_CHAR_DISTANCE_INFO; - } else if ((mExceeding || mTransposing) && mInputIndex - 1 < mInputLength + } else if ((mExceeding || mTransposing) && mInputIndex - 1 < mInputSize && isEquivalentChar( mProximityInfoState.getMatchedProximityId(mInputIndex + 1, c, false))) { // 1.2. Excessive or transpose correction @@ -513,7 +513,7 @@ Correction::CorrectionType Correction::processCharAndCalcState( incrementInputIndex(); } if (DEBUG_CORRECTION - && (INPUTLENGTH_FOR_DEBUG <= 0 || INPUTLENGTH_FOR_DEBUG == mInputLength) + && (INPUTLENGTH_FOR_DEBUG <= 0 || INPUTLENGTH_FOR_DEBUG == mInputSize) && (MIN_OUTPUT_INDEX_FOR_DEBUG <= 0 || MIN_OUTPUT_INDEX_FOR_DEBUG < mOutputIndex)) { DUMP_WORD(mWord, mOutputIndex); @@ -529,7 +529,7 @@ Correction::CorrectionType Correction::processCharAndCalcState( // 3. Skip correction ++mSkippedCount; if (DEBUG_CORRECTION - && (INPUTLENGTH_FOR_DEBUG <= 0 || INPUTLENGTH_FOR_DEBUG == mInputLength) + && (INPUTLENGTH_FOR_DEBUG <= 0 || INPUTLENGTH_FOR_DEBUG == mInputSize) && (MIN_OUTPUT_INDEX_FOR_DEBUG <= 0 || MIN_OUTPUT_INDEX_FOR_DEBUG < mOutputIndex)) { AKLOGI("SKIP: %d, %d, %d, %d, %c", mProximityCount, mSkippedCount, @@ -542,7 +542,7 @@ Correction::CorrectionType Correction::processCharAndCalcState( ++mProximityCount; mDistances[mOutputIndex] = ADDITIONAL_PROXIMITY_CHAR_DISTANCE_INFO; if (DEBUG_CORRECTION - && (INPUTLENGTH_FOR_DEBUG <= 0 || INPUTLENGTH_FOR_DEBUG == mInputLength) + && (INPUTLENGTH_FOR_DEBUG <= 0 || INPUTLENGTH_FOR_DEBUG == mInputSize) && (MIN_OUTPUT_INDEX_FOR_DEBUG <= 0 || MIN_OUTPUT_INDEX_FOR_DEBUG < mOutputIndex)) { AKLOGI("ADDITIONALPROX: %d, %d, %d, %d, %c", mProximityCount, mSkippedCount, @@ -550,7 +550,7 @@ Correction::CorrectionType Correction::processCharAndCalcState( } } else { if (DEBUG_CORRECTION - && (INPUTLENGTH_FOR_DEBUG <= 0 || INPUTLENGTH_FOR_DEBUG == mInputLength) + && (INPUTLENGTH_FOR_DEBUG <= 0 || INPUTLENGTH_FOR_DEBUG == mInputSize) && (MIN_OUTPUT_INDEX_FOR_DEBUG <= 0 || MIN_OUTPUT_INDEX_FOR_DEBUG < mOutputIndex)) { DUMP_WORD(mWord, mOutputIndex); @@ -560,7 +560,7 @@ Correction::CorrectionType Correction::processCharAndCalcState( return processUnrelatedCorrectionType(); } } else if (secondTransposing) { - // If inputIndex is greater than mInputLength, that means there is no + // If inputIndex is greater than mInputSize, that means there is no // proximity chars. So, we don't need to check proximity. mMatching = true; } else if (isEquivalentChar(matchedProximityCharId)) { @@ -573,7 +573,7 @@ Correction::CorrectionType Correction::processCharAndCalcState( mDistances[mOutputIndex] = mProximityInfoState.getNormalizedSquaredDistance(mInputIndex, proximityIndex); if (DEBUG_CORRECTION - && (INPUTLENGTH_FOR_DEBUG <= 0 || INPUTLENGTH_FOR_DEBUG == mInputLength) + && (INPUTLENGTH_FOR_DEBUG <= 0 || INPUTLENGTH_FOR_DEBUG == mInputSize) && (MIN_OUTPUT_INDEX_FOR_DEBUG <= 0 || MIN_OUTPUT_INDEX_FOR_DEBUG < mOutputIndex)) { AKLOGI("PROX: %d, %d, %d, %d, %c", mProximityCount, mSkippedCount, @@ -585,8 +585,8 @@ Correction::CorrectionType Correction::processCharAndCalcState( // 4. Last char excessive correction mLastCharExceeded = mExcessiveCount == 0 && mSkippedCount == 0 && mTransposedCount == 0 - && mProximityCount == 0 && (mInputIndex == mInputLength - 2); - const bool isSameAsUserTypedLength = (mInputLength == mInputIndex + 1) || mLastCharExceeded; + && mProximityCount == 0 && (mInputIndex == mInputSize - 2); + const bool isSameAsUserTypedLength = (mInputSize == mInputIndex + 1) || mLastCharExceeded; if (mLastCharExceeded) { ++mExcessiveCount; } @@ -597,7 +597,7 @@ Correction::CorrectionType Correction::processCharAndCalcState( } const bool needsToTryOnTerminalForTheLastPossibleExcessiveChar = - mExceeding && mInputIndex == mInputLength - 2; + mExceeding && mInputIndex == mInputSize - 2; // Finally, we are ready to go to the next character, the next "virtual node". // We should advance the input index. @@ -613,7 +613,7 @@ Correction::CorrectionType Correction::processCharAndCalcState( mTerminalInputIndex = mInputIndex - 1; mTerminalOutputIndex = mOutputIndex - 1; if (DEBUG_CORRECTION - && (INPUTLENGTH_FOR_DEBUG <= 0 || INPUTLENGTH_FOR_DEBUG == mInputLength) + && (INPUTLENGTH_FOR_DEBUG <= 0 || INPUTLENGTH_FOR_DEBUG == mInputSize) && (MIN_OUTPUT_INDEX_FOR_DEBUG <= 0 || MIN_OUTPUT_INDEX_FOR_DEBUG < mOutputIndex)) { DUMP_WORD(mWord, mOutputIndex); AKLOGI("ONTERMINAL(1): %d, %d, %d, %d, %c", mProximityCount, mSkippedCount, @@ -651,7 +651,7 @@ inline static bool isUpperCase(unsigned short c) { /* static */ int Correction::RankingAlgorithm::calculateFinalProbability(const int inputIndex, const int outputIndex, const int freq, int *editDistanceTable, const Correction *correction, - const int inputLength) { + const int inputSize) { const int excessivePos = correction->getExcessivePos(); const int typedLetterMultiplier = correction->TYPED_LETTER_MULTIPLIER; const int fullWordMultiplier = correction->FULL_WORD_MULTIPLIER; @@ -663,55 +663,55 @@ int Correction::RankingAlgorithm::calculateFinalProbability(const int inputIndex const bool lastCharExceeded = correction->mLastCharExceeded; const bool useFullEditDistance = correction->mUseFullEditDistance; const int outputLength = outputIndex + 1; - if (skippedCount >= inputLength || inputLength == 0) { + if (skippedCount >= inputSize || inputSize == 0) { return -1; } // TODO: find more robust way - bool sameLength = lastCharExceeded ? (inputLength == inputIndex + 2) - : (inputLength == inputIndex + 1); + bool sameLength = lastCharExceeded ? (inputSize == inputIndex + 2) + : (inputSize == inputIndex + 1); // TODO: use mExcessiveCount - const int matchCount = inputLength - correction->mProximityCount - excessiveCount; + const int matchCount = inputSize - correction->mProximityCount - excessiveCount; const unsigned short *word = correction->mWord; const bool skipped = skippedCount > 0; const int quoteDiffCount = max(0, getQuoteCount(word, outputLength) - - getQuoteCount(proximityInfoState->getPrimaryInputWord(), inputLength)); + - getQuoteCount(proximityInfoState->getPrimaryInputWord(), inputSize)); // TODO: Calculate edit distance for transposed and excessive int ed = 0; if (DEBUG_DICT_FULL) { - dumpEditDistance10ForDebug(editDistanceTable, correction->mInputLength, outputLength); + dumpEditDistance10ForDebug(editDistanceTable, correction->mInputSize, outputLength); } int adjustedProximityMatchedCount = proximityMatchedCount; int finalFreq = freq; if (DEBUG_CORRECTION_FREQ - && (INPUTLENGTH_FOR_DEBUG <= 0 || INPUTLENGTH_FOR_DEBUG == inputLength)) { + && (INPUTLENGTH_FOR_DEBUG <= 0 || INPUTLENGTH_FOR_DEBUG == inputSize)) { AKLOGI("FinalFreq0: %d", finalFreq); } // TODO: Optimize this. if (transposedCount > 0 || proximityMatchedCount > 0 || skipped || excessiveCount > 0) { - ed = getCurrentEditDistance(editDistanceTable, correction->mInputLength, outputLength, - inputLength) - transposedCount; + ed = getCurrentEditDistance(editDistanceTable, correction->mInputSize, outputLength, + inputSize) - transposedCount; const int matchWeight = powerIntCapped(typedLetterMultiplier, - max(inputLength, outputLength) - ed); + max(inputSize, outputLength) - ed); multiplyIntCapped(matchWeight, &finalFreq); // TODO: Demote further if there are two or more excessive chars with longer user input? - if (inputLength > outputLength) { + if (inputSize > outputLength) { multiplyRate(INPUT_EXCEEDS_OUTPUT_DEMOTION_RATE, &finalFreq); } ed = max(0, ed - quoteDiffCount); - adjustedProximityMatchedCount = min(max(0, ed - (outputLength - inputLength)), + adjustedProximityMatchedCount = min(max(0, ed - (outputLength - inputSize)), proximityMatchedCount); if (transposedCount <= 0) { - if (ed == 1 && (inputLength == outputLength - 1 || inputLength == outputLength + 1)) { + if (ed == 1 && (inputSize == outputLength - 1 || inputSize == outputLength + 1)) { // Promote a word with just one skipped or excessive char if (sameLength) { multiplyRate(WORDS_WITH_JUST_ONE_CORRECTION_PROMOTION_RATE @@ -740,8 +740,8 @@ int Correction::RankingAlgorithm::calculateFinalProbability(const int inputIndex // Demotion for a word with missing character if (skipped) { const int demotionRate = WORDS_WITH_MISSING_CHARACTER_DEMOTION_RATE - * (10 * inputLength - WORDS_WITH_MISSING_CHARACTER_DEMOTION_START_POS_10X) - / (10 * inputLength + * (10 * inputSize - WORDS_WITH_MISSING_CHARACTER_DEMOTION_START_POS_10X) + / (10 * inputSize - WORDS_WITH_MISSING_CHARACTER_DEMOTION_START_POS_10X + 10); if (DEBUG_DICT_FULL) { AKLOGI("Demotion rate for missing character is %d.", demotionRate); @@ -843,7 +843,7 @@ int Correction::RankingAlgorithm::calculateFinalProbability(const int inputIndex ? adjustedProximityMatchedCount : (proximityMatchedCount + transposedCount); multiplyRate( - 100 - CORRECTION_COUNT_RATE_DEMOTION_RATE_BASE * errorCount / inputLength, &finalFreq); + 100 - CORRECTION_COUNT_RATE_DEMOTION_RATE_BASE * errorCount / inputSize, &finalFreq); // Promotion for an exactly matched word if (ed == 0) { @@ -878,7 +878,7 @@ int Correction::RankingAlgorithm::calculateFinalProbability(const int inputIndex e ... exceeding p ... proximity matching */ - if (matchCount == inputLength && matchCount >= 2 && !skipped + if (matchCount == inputSize && matchCount >= 2 && !skipped && word[matchCount] == word[matchCount - 1]) { multiplyRate(WORDS_WITH_MATCH_SKIP_PROMOTION_RATE, &finalFreq); } @@ -888,8 +888,8 @@ int Correction::RankingAlgorithm::calculateFinalProbability(const int inputIndex multiplyIntCapped(fullWordMultiplier, &finalFreq); } - if (useFullEditDistance && outputLength > inputLength + 1) { - const int diff = outputLength - inputLength - 1; + if (useFullEditDistance && outputLength > inputSize + 1) { + const int diff = outputLength - inputSize - 1; const int divider = diff < 31 ? 1 << diff : S_INT_MAX; finalFreq = divider > finalFreq ? 1 : finalFreq / divider; } @@ -899,8 +899,8 @@ int Correction::RankingAlgorithm::calculateFinalProbability(const int inputIndex } if (DEBUG_CORRECTION_FREQ - && (INPUTLENGTH_FOR_DEBUG <= 0 || INPUTLENGTH_FOR_DEBUG == inputLength)) { - DUMP_WORD(correction->getPrimaryInputWord(), inputLength); + && (INPUTLENGTH_FOR_DEBUG <= 0 || INPUTLENGTH_FOR_DEBUG == inputSize)) { + DUMP_WORD(correction->getPrimaryInputWord(), inputSize); DUMP_WORD(correction->mWord, outputLength); AKLOGI("FinalFreq: [P%d, S%d, T%d, E%d, A%d] %d, %d, %d, %d, %d, %d", proximityMatchedCount, skippedCount, transposedCount, excessiveCount, additionalProximityCount, diff --git a/native/jni/src/correction.h b/native/jni/src/correction.h index 9899f6e66..c90c8d553 100644 --- a/native/jni/src/correction.h +++ b/native/jni/src/correction.h @@ -42,7 +42,7 @@ class Correction { virtual ~Correction(); void resetCorrection(); void initCorrection( - const ProximityInfo *pi, const int inputLength, const int maxWordLength); + const ProximityInfo *pi, const int inputSize, const int maxWordLength); void initCorrectionState(const int rootPos, const int childCount, const bool traverseAll); // TODO: remove @@ -66,7 +66,7 @@ class Correction { const bool isSpaceProximity, const unsigned short *word); int getFinalProbability(const int probability, unsigned short **word, int *wordLength); int getFinalProbabilityForSubQueue(const int probability, unsigned short **word, - int *wordLength, const int inputLength); + int *wordLength, const int inputSize); CorrectionType processCharAndCalcState(const int32_t c, const bool isTerminal); @@ -90,7 +90,7 @@ class Correction { public: static int calculateFinalProbability(const int inputIndex, const int depth, const int probability, int *editDistanceTable, const Correction *correction, - const int inputLength); + const int inputSize); static int calcFreqForSplitMultipleWords(const int *freqArray, const int *wordLengthArray, const int wordCount, const Correction *correction, const bool isSpaceProximity, const unsigned short *word); @@ -105,9 +105,9 @@ class Correction { // proximity info state void initInputParams(const ProximityInfo *proximityInfo, const int32_t *inputCodes, - const int inputLength, const int *xCoordinates, const int *yCoordinates) { - mProximityInfoState.initInputParams( - proximityInfo, inputCodes, inputLength, xCoordinates, yCoordinates); + const int inputSize, const int *xCoordinates, const int *yCoordinates) { + mProximityInfoState.initInputParams(0, MAX_POINT_TO_KEY_LENGTH, + proximityInfo, inputCodes, inputSize, xCoordinates, yCoordinates, 0, 0, false); } const unsigned short *getPrimaryInputWord() const { @@ -204,7 +204,7 @@ class Correction { inline CorrectionType processUnrelatedCorrectionType(); inline void addCharToCurrentWord(const int32_t c); inline int getFinalProbabilityInternal(const int probability, unsigned short **word, - int *wordLength, const int inputLength); + int *wordLength, const int inputSize); static const int TYPED_LETTER_MULTIPLIER = 2; static const int FULL_WORD_MULTIPLIER = 2; @@ -214,7 +214,7 @@ class Correction { bool mDoAutoCompletion; int mMaxEditDistance; int mMaxDepth; - int mInputLength; + int mInputSize; int mSpaceProximityPos; int mMissingSpacePos; int mTerminalInputIndex; diff --git a/native/jni/src/defines.h b/native/jni/src/defines.h index 929b303d6..9b530077a 100644 --- a/native/jni/src/defines.h +++ b/native/jni/src/defines.h @@ -294,6 +294,9 @@ static inline void prof_out(void) { #define MAX_SPACES_INTERNAL 16 +// Max Distance between point to key +#define MAX_POINT_TO_KEY_LENGTH 10000000 + // TODO: Reduce this constant if possible; check the maximum number of digraphs in the same // word in the dictionary for languages with digraphs, like German and French #define DEFAULT_MAX_DIGRAPH_SEARCH_DEPTH 5 diff --git a/native/jni/src/geometry_utils.h b/native/jni/src/geometry_utils.h index 146eb8055..f30e9fcc0 100644 --- a/native/jni/src/geometry_utils.h +++ b/native/jni/src/geometry_utils.h @@ -19,7 +19,6 @@ #include <cmath> -#define MAX_DISTANCE 10000000 #define MAX_PATHS 2 #define DEBUG_DECODER false diff --git a/native/jni/src/proximity_info_state.cpp b/native/jni/src/proximity_info_state.cpp index 86c8a697a..0bb6dd9cb 100644 --- a/native/jni/src/proximity_info_state.cpp +++ b/native/jni/src/proximity_info_state.cpp @@ -20,13 +20,15 @@ #define LOG_TAG "LatinIME: proximity_info_state.cpp" #include "defines.h" +#include "geometry_utils.h" #include "proximity_info.h" #include "proximity_info_state.h" namespace latinime { -void ProximityInfoState::initInputParams( - const ProximityInfo *proximityInfo, const int32_t *inputCodes, const int inputLength, - const int *xCoordinates, const int *yCoordinates) { +void ProximityInfoState::initInputParams(const int pointerId, const float maxLength, + const ProximityInfo *proximityInfo, const int32_t *inputCodes, const int inputSize, + const int *const xCoordinates, const int *const yCoordinates, const int *const times, + const int *const pointerIds, const bool isGeometric) { mProximityInfo = proximityInfo; mHasTouchPositionCorrectionData = proximityInfo->hasTouchPositionCorrectionData(); mMostCommonKeyWidthSquare = proximityInfo->getMostCommonKeyWidthSquare(); @@ -45,7 +47,7 @@ void ProximityInfoState::initInputParams( memset(mInputCodes, 0, MAX_WORD_LENGTH_INTERNAL * MAX_PROXIMITY_CHARS_SIZE_INTERNAL * sizeof(mInputCodes[0])); - for (int i = 0; i < inputLength; ++i) { + for (int i = 0; i < inputSize; ++i) { const int32_t primaryKey = inputCodes[i]; const int x = xCoordinates[i]; const int y = yCoordinates[i]; @@ -54,7 +56,7 @@ void ProximityInfoState::initInputParams( } if (DEBUG_PROXIMITY_CHARS) { - for (int i = 0; i < inputLength; ++i) { + for (int i = 0; i < inputSize; ++i) { AKLOGI("---"); for (int j = 0; j < MAX_PROXIMITY_CHARS_SIZE_INTERNAL; ++j) { int icc = mInputCodes[i * MAX_PROXIMITY_CHARS_SIZE_INTERNAL + j]; @@ -65,19 +67,57 @@ void ProximityInfoState::initInputParams( } } } - mInputXCoordinates = xCoordinates; - mInputYCoordinates = yCoordinates; - mTouchPositionCorrectionEnabled = - mHasTouchPositionCorrectionData && xCoordinates && yCoordinates; - mInputLength = inputLength; - for (int i = 0; i < inputLength; ++i) { - mPrimaryInputWord[i] = getPrimaryCharAt(i); + + mMaxPointToKeyLength = maxLength; + /////////////////////// + // Setup touch points + mInputXs.clear(); + mInputYs.clear(); + mTimes.clear(); + mLengthCache.clear(); + mDistanceCache.clear(); + + mInputSize = 0; + if (xCoordinates && yCoordinates) { + const bool proximityOnly = !isGeometric && (xCoordinates[0] < 0 || yCoordinates[0] < 0); + for (int i = 0; i < inputSize; ++i) { + ++mInputSize; + // Assuming pointerId == 0 if pointerIds is null. + const int pid = pointerIds ? pointerIds[i] : 0; + if (pointerId == pid) { + const int c = isGeometric ? NOT_A_COORDINATE : getPrimaryCharAt(i); + const int x = proximityOnly ? NOT_A_COORDINATE : xCoordinates[i]; + const int y = proximityOnly ? NOT_A_COORDINATE : yCoordinates[i]; + const int time = times ? times[i] : -1; + pushTouchPoint(c, x, y, time, isGeometric); + } + } } - mPrimaryInputWord[inputLength] = 0; - if (DEBUG_PROXIMITY_CHARS) { - AKLOGI("--- initInputParams"); + + if (mInputSize > 0) { + const int keyCount = mProximityInfo->getKeyCount(); + mDistanceCache.resize(mInputSize * keyCount); + for (int i = 0; i < mInputSize; ++i) { + for (int k = 0; k < keyCount; ++k) { + const int index = i * keyCount + k; + const int x = mInputXs[i]; + const int y = mInputYs[i]; + mDistanceCache[index] = + mProximityInfo->getNormalizedSquaredDistanceFromCenterFloat(k, x, y); + } + } + } + // end + /////////////////////// + + for (int i = 0; i < inputSize; ++i) { + mPrimaryInputWord[i] = getPrimaryCharAt(i); } - for (int i = 0; i < mInputLength; ++i) { + mPrimaryInputWord[inputSize] = 0; + + mTouchPositionCorrectionEnabled = + mHasTouchPositionCorrectionData && xCoordinates && yCoordinates && !isGeometric; + for (int i = 0; i < mInputSize && mTouchPositionCorrectionEnabled; ++i) { const int *proximityChars = getProximityCharsAt(i); const int primaryKey = proximityChars[0]; const int x = xCoordinates[i]; @@ -108,6 +148,32 @@ void ProximityInfoState::initInputParams( } } +void ProximityInfoState::pushTouchPoint(const int nodeChar, int x, int y, + const int time, const bool sample) { + const uint32_t size = mInputXs.size(); + // TODO: Should have a const variable for 10 + const int sampleRate = mProximityInfo->getMostCommonKeyWidth() / 10; + if (size > 0) { + const int dist = getDistanceInt(x, y, mInputXs[size - 1], mInputYs[size - 1]); + if (sample && dist < sampleRate) { + return; + } + mLengthCache.push_back(mLengthCache[size - 1] + dist); + } else { + mLengthCache.push_back(0); + } + if (nodeChar >= 0 && (x < 0 || y < 0)) { + const int keyId = mProximityInfo->getKeyIndex(nodeChar); + if (keyId >= 0) { + x = mProximityInfo->getKeyCenterXOfIdG(keyId); + y = mProximityInfo->getKeyCenterYOfIdG(keyId); + } + } + mInputXs.push_back(x); + mInputYs.push_back(y); + mTimes.push_back(time); +} + float ProximityInfoState::calculateNormalizedSquaredDistance( const int keyIndex, const int inputIndex) const { if (keyIndex == NOT_AN_INDEX) { @@ -116,7 +182,7 @@ float ProximityInfoState::calculateNormalizedSquaredDistance( if (!mProximityInfo->hasSweetSpotData(keyIndex)) { return NOT_A_DISTANCE_FLOAT; } - if (NOT_A_COORDINATE == mInputXCoordinates[inputIndex]) { + if (NOT_A_COORDINATE == mInputXs[inputIndex]) { return NOT_A_DISTANCE_FLOAT; } const float squaredDistance = calculateSquaredDistanceFromSweetSpotCenter( @@ -125,12 +191,37 @@ float ProximityInfoState::calculateNormalizedSquaredDistance( return squaredDistance / squaredRadius; } +int ProximityInfoState::getDuration(const int index) const { + if (mTimes.size() == 0 || index <= 0 || index >= static_cast<int>(mInputSize) - 1) { + return 0; + } + return mTimes[index + 1] - mTimes[index - 1]; +} + +float ProximityInfoState::getPointToKeyLength(int inputIndex, int charCode, float scale) { + const int keyId = mProximityInfo->getKeyIndex(charCode); + if (keyId >= 0) { + const int index = inputIndex * mProximityInfo->getKeyCount() + keyId; + return min(mDistanceCache[index] * scale, mMaxPointToKeyLength); + } + return 0; +} + +int ProximityInfoState::getKeyKeyDistance(int key0, int key1) { + return mProximityInfo->getKeyKeyDistanceG(key0, key1); +} + +int ProximityInfoState::getSpaceY() { + const int keyId = mProximityInfo->getKeyIndex(' '); + return mProximityInfo->getKeyCenterYOfIdG(keyId); +} + float ProximityInfoState::calculateSquaredDistanceFromSweetSpotCenter( const int keyIndex, const int inputIndex) const { const float sweetSpotCenterX = mProximityInfo->getSweetSpotCenterXAt(keyIndex); const float sweetSpotCenterY = mProximityInfo->getSweetSpotCenterYAt(keyIndex); - const float inputX = static_cast<float>(mInputXCoordinates[inputIndex]); - const float inputY = static_cast<float>(mInputYCoordinates[inputIndex]); + const float inputX = static_cast<float>(mInputXs[inputIndex]); + const float inputY = static_cast<float>(mInputYs[inputIndex]); return square(inputX - sweetSpotCenterX) + square(inputY - sweetSpotCenterY); } } // namespace latinime diff --git a/native/jni/src/proximity_info_state.h b/native/jni/src/proximity_info_state.h index 2fb0ae044..81d68fdcb 100644 --- a/native/jni/src/proximity_info_state.h +++ b/native/jni/src/proximity_info_state.h @@ -19,6 +19,7 @@ #include <stdint.h> #include <string> +#include <vector> #include "char_utils.h" #include "defines.h" @@ -40,9 +41,10 @@ class ProximityInfoState { ///////////////////////////////////////// // Defined in proximity_info_state.cpp // ///////////////////////////////////////// - void initInputParams( - const ProximityInfo *proximityInfo, const int32_t *inputCodes, const int inputLength, - const int *xCoordinates, const int *yCoordinates); + void initInputParams(const int pointerId, const float maxLength, + const ProximityInfo *proximityInfo, const int32_t *inputCodes, const int inputSize, + const int *xCoordinates, const int *yCoordinates, const int *const times, + const int *const pointerIds, const bool isGeometric); ///////////////////////////////////////// // Defined here // @@ -65,14 +67,14 @@ class ProximityInfoState { } inline bool existsAdjacentProximityChars(const int index) const { - if (index < 0 || index >= mInputLength) return false; + if (index < 0 || index >= mInputSize) return false; const int currentChar = getPrimaryCharAt(index); const int leftIndex = index - 1; if (leftIndex >= 0 && existsCharInProximityAt(leftIndex, currentChar)) { return true; } const int rightIndex = index + 1; - if (rightIndex < mInputLength && existsCharInProximityAt(rightIndex, currentChar)) { + if (rightIndex < mInputSize && existsCharInProximityAt(rightIndex, currentChar)) { return true; } return false; @@ -158,7 +160,7 @@ class ProximityInfoState { } inline bool sameAsTyped(const unsigned short *word, int length) const { - if (length != mInputLength) { + if (length != mInputSize) { return false; } const int *inputCodes = mInputCodes; @@ -172,6 +174,18 @@ class ProximityInfoState { return true; } + int getDuration(const int index) const; + + bool isUsed() const { + return mInputSize > 0; + } + + float getPointToKeyLength(int inputIndex, int charCode, float scale); + + int getKeyKeyDistance(int key0, int key1); + + int getSpaceY(); + private: DISALLOW_COPY_AND_ASSIGN(ProximityInfoState); ///////////////////////////////////////// @@ -182,13 +196,14 @@ class ProximityInfoState { float calculateSquaredDistanceFromSweetSpotCenter( const int keyIndex, const int inputIndex) const; + void pushTouchPoint(const int nodeChar, int x, int y, const int time, const bool sample); ///////////////////////////////////////// // Defined here // ///////////////////////////////////////// inline float square(const float x) const { return x * x; } bool hasInputCoordinates() const { - return mInputXCoordinates && mInputYCoordinates; + return mInputXs.size() > 0 && mInputYs.size() > 0; } inline const int *getProximityCharsAt(const int index) const { @@ -197,6 +212,7 @@ class ProximityInfoState { // const const ProximityInfo *mProximityInfo; + float mMaxPointToKeyLength; bool mHasTouchPositionCorrectionData; int mMostCommonKeyWidthSquare; std::string mLocaleStr; @@ -206,12 +222,15 @@ class ProximityInfoState { int mGridHeight; int mGridWidth; - const int *mInputXCoordinates; - const int *mInputYCoordinates; + std::vector<int> mInputXs; + std::vector<int> mInputYs; + std::vector<int> mTimes; + std::vector<float> mDistanceCache; + std::vector<int> mLengthCache; bool mTouchPositionCorrectionEnabled; int32_t mInputCodes[MAX_PROXIMITY_CHARS_SIZE_INTERNAL * MAX_WORD_LENGTH_INTERNAL]; int mNormalizedSquaredDistances[MAX_PROXIMITY_CHARS_SIZE_INTERNAL * MAX_WORD_LENGTH_INTERNAL]; - int mInputLength; + int mInputSize; unsigned short mPrimaryInputWord[MAX_WORD_LENGTH_INTERNAL]; }; } // namespace latinime diff --git a/native/jni/src/unigram_dictionary.cpp b/native/jni/src/unigram_dictionary.cpp index 705defc00..ba3c2db6b 100644 --- a/native/jni/src/unigram_dictionary.cpp +++ b/native/jni/src/unigram_dictionary.cpp @@ -237,7 +237,7 @@ int UnigramDictionary::getSuggestions(ProximityInfo *proximityInfo, void UnigramDictionary::getWordSuggestions(ProximityInfo *proximityInfo, const int *xcoordinates, const int *ycoordinates, const int *codes, - const int inputLength, const std::map<int, int> *bigramMap, const uint8_t *bigramFilter, + const int inputSize, const std::map<int, int> *bigramMap, const uint8_t *bigramFilter, const bool useFullEditDistance, Correction *correction, WordsPriorityQueuePool *queuePool) const { @@ -247,7 +247,7 @@ void UnigramDictionary::getWordSuggestions(ProximityInfo *proximityInfo, PROF_START(1); getOneWordSuggestions(proximityInfo, xcoordinates, ycoordinates, codes, bigramMap, bigramFilter, - useFullEditDistance, inputLength, correction, queuePool); + useFullEditDistance, inputSize, correction, queuePool); PROF_END(1); PROF_START(2); @@ -263,7 +263,7 @@ void UnigramDictionary::getWordSuggestions(ProximityInfo *proximityInfo, WordsPriorityQueue *masterQueue = queuePool->getMasterQueue(); if (masterQueue->size() > 0) { float nsForMaster = masterQueue->getHighestNormalizedScore( - correction->getPrimaryInputWord(), inputLength, 0, 0, 0); + correction->getPrimaryInputWord(), inputSize, 0, 0, 0); hasAutoCorrectionCandidate = (nsForMaster > START_TWO_WORDS_CORRECTION_THRESHOLD); } PROF_END(4); @@ -271,9 +271,9 @@ void UnigramDictionary::getWordSuggestions(ProximityInfo *proximityInfo, PROF_START(5); // Multiple word suggestions if (SUGGEST_MULTIPLE_WORDS - && inputLength >= MIN_USER_TYPED_LENGTH_FOR_MULTIPLE_WORD_SUGGESTION) { + && inputSize >= MIN_USER_TYPED_LENGTH_FOR_MULTIPLE_WORD_SUGGESTION) { getSplitMultipleWordsSuggestions(proximityInfo, xcoordinates, ycoordinates, codes, - useFullEditDistance, inputLength, correction, queuePool, + useFullEditDistance, inputSize, correction, queuePool, hasAutoCorrectionCandidate); } PROF_END(5); @@ -304,15 +304,15 @@ void UnigramDictionary::getWordSuggestions(ProximityInfo *proximityInfo, } void UnigramDictionary::initSuggestions(ProximityInfo *proximityInfo, const int *xCoordinates, - const int *yCoordinates, const int *codes, const int inputLength, + const int *yCoordinates, const int *codes, const int inputSize, Correction *correction) const { if (DEBUG_DICT) { AKLOGI("initSuggest"); - DUMP_WORD_INT(codes, inputLength); + DUMP_WORD_INT(codes, inputSize); } - correction->initInputParams(proximityInfo, codes, inputLength, xCoordinates, yCoordinates); - const int maxDepth = min(inputLength * MAX_DEPTH_MULTIPLIER, MAX_WORD_LENGTH); - correction->initCorrection(proximityInfo, inputLength, maxDepth); + correction->initInputParams(proximityInfo, codes, inputSize, xCoordinates, yCoordinates); + const int maxDepth = min(inputSize * MAX_DEPTH_MULTIPLIER, MAX_WORD_LENGTH); + correction->initCorrection(proximityInfo, inputSize, maxDepth); } static const char QUOTE = '\''; @@ -321,15 +321,15 @@ static const char SPACE = ' '; void UnigramDictionary::getOneWordSuggestions(ProximityInfo *proximityInfo, const int *xcoordinates, const int *ycoordinates, const int *codes, const std::map<int, int> *bigramMap, const uint8_t *bigramFilter, - const bool useFullEditDistance, const int inputLength, + const bool useFullEditDistance, const int inputSize, Correction *correction, WordsPriorityQueuePool *queuePool) const { - initSuggestions(proximityInfo, xcoordinates, ycoordinates, codes, inputLength, correction); - getSuggestionCandidates(useFullEditDistance, inputLength, bigramMap, bigramFilter, correction, + initSuggestions(proximityInfo, xcoordinates, ycoordinates, codes, inputSize, correction); + getSuggestionCandidates(useFullEditDistance, inputSize, bigramMap, bigramFilter, correction, queuePool, true /* doAutoCompletion */, DEFAULT_MAX_ERRORS, FIRST_WORD_INDEX); } void UnigramDictionary::getSuggestionCandidates(const bool useFullEditDistance, - const int inputLength, const std::map<int, int> *bigramMap, const uint8_t *bigramFilter, + const int inputSize, const std::map<int, int> *bigramMap, const uint8_t *bigramFilter, Correction *correction, WordsPriorityQueuePool *queuePool, const bool doAutoCompletion, const int maxErrors, const int currentWordIndex) const { uint8_t totalTraverseCount = correction->pushAndGetTotalTraverseCount(); @@ -351,7 +351,7 @@ void UnigramDictionary::getSuggestionCandidates(const bool useFullEditDistance, int childCount = BinaryFormat::getGroupCountAndForwardPointer(DICT_ROOT, &rootPosition); int outputIndex = 0; - correction->initCorrectionState(rootPosition, childCount, (inputLength <= 0)); + correction->initCorrectionState(rootPosition, childCount, (inputSize <= 0)); // Depth first search while (outputIndex >= 0) { @@ -446,7 +446,7 @@ inline void UnigramDictionary::onTerminal(const int probability, int UnigramDictionary::getSubStringSuggestion( ProximityInfo *proximityInfo, const int *xcoordinates, const int *ycoordinates, const int *codes, const bool useFullEditDistance, Correction *correction, - WordsPriorityQueuePool *queuePool, const int inputLength, + WordsPriorityQueuePool *queuePool, const int inputSize, const bool hasAutoCorrectionCandidate, const int currentWordIndex, const int inputWordStartPos, const int inputWordLength, const int outputWordStartPos, const bool isSpaceProximity, int *freqArray, @@ -497,7 +497,7 @@ int UnigramDictionary::getSubStringSuggestion( int nextWordLength = 0; // TODO: Optimize init suggestion initSuggestions(proximityInfo, xcoordinates, ycoordinates, codes, - inputLength, correction); + inputSize, correction); unsigned short word[MAX_WORD_LENGTH_INTERNAL]; int freq = getMostFrequentWordLike( @@ -566,7 +566,7 @@ int UnigramDictionary::getSubStringSuggestion( *outputWordLength = tempOutputWordLength; } - if ((inputWordStartPos + inputWordLength) < inputLength) { + if ((inputWordStartPos + inputWordLength) < inputSize) { if (outputWordStartPos + nextWordLength >= MAX_WORD_LENGTH) { return FLAG_MULTIPLE_SUGGEST_SKIP; } @@ -585,7 +585,7 @@ int UnigramDictionary::getSubStringSuggestion( freqArray[i], wordLengthArray[i]); } AKLOGI("Split two words: freq = %d, length = %d, %d, isSpace ? %d", pairFreq, - inputLength, tempOutputWordLength, isSpaceProximity); + inputSize, tempOutputWordLength, isSpaceProximity); } addWord(outputWord, tempOutputWordLength, pairFreq, queuePool->getMasterQueue(), Dictionary::KIND_CORRECTION); @@ -595,7 +595,7 @@ int UnigramDictionary::getSubStringSuggestion( void UnigramDictionary::getMultiWordsSuggestionRec(ProximityInfo *proximityInfo, const int *xcoordinates, const int *ycoordinates, const int *codes, - const bool useFullEditDistance, const int inputLength, + const bool useFullEditDistance, const int inputSize, Correction *correction, WordsPriorityQueuePool *queuePool, const bool hasAutoCorrectionCandidate, const int startInputPos, const int startWordIndex, const int outputWordLength, int *freqArray, int *wordLengthArray, @@ -606,11 +606,11 @@ void UnigramDictionary::getMultiWordsSuggestionRec(ProximityInfo *proximityInfo, } if (startWordIndex >= 1 && (hasAutoCorrectionCandidate - || inputLength < MIN_INPUT_LENGTH_FOR_THREE_OR_MORE_WORDS_CORRECTION)) { + || inputSize < MIN_INPUT_LENGTH_FOR_THREE_OR_MORE_WORDS_CORRECTION)) { // Do not suggest 3+ words if already has auto correction candidate return; } - for (int i = startInputPos + 1; i < inputLength; ++i) { + for (int i = startInputPos + 1; i < inputSize; ++i) { if (DEBUG_CORRECTION_FREQ) { AKLOGI("Multi words(%d), start in %d sep %d start out %d", startWordIndex, startInputPos, i, outputWordLength); @@ -621,7 +621,7 @@ void UnigramDictionary::getMultiWordsSuggestionRec(ProximityInfo *proximityInfo, int inputWordStartPos = startInputPos; int inputWordLength = i - startInputPos; const int suggestionFlag = getSubStringSuggestion(proximityInfo, xcoordinates, ycoordinates, - codes, useFullEditDistance, correction, queuePool, inputLength, + codes, useFullEditDistance, correction, queuePool, inputSize, hasAutoCorrectionCandidate, startWordIndex, inputWordStartPos, inputWordLength, outputWordLength, true /* not used */, freqArray, wordLengthArray, outputWord, &tempOutputWordLength); @@ -638,14 +638,14 @@ void UnigramDictionary::getMultiWordsSuggestionRec(ProximityInfo *proximityInfo, // Next word // Missing space inputWordStartPos = i; - inputWordLength = inputLength - i; + inputWordLength = inputSize - i; if(getSubStringSuggestion(proximityInfo, xcoordinates, ycoordinates, codes, - useFullEditDistance, correction, queuePool, inputLength, hasAutoCorrectionCandidate, + useFullEditDistance, correction, queuePool, inputSize, hasAutoCorrectionCandidate, startWordIndex + 1, inputWordStartPos, inputWordLength, tempOutputWordLength, false /* missing space */, freqArray, wordLengthArray, outputWord, 0) != FLAG_MULTIPLE_SUGGEST_CONTINUE) { getMultiWordsSuggestionRec(proximityInfo, xcoordinates, ycoordinates, codes, - useFullEditDistance, inputLength, correction, queuePool, + useFullEditDistance, inputSize, correction, queuePool, hasAutoCorrectionCandidate, inputWordStartPos, startWordIndex + 1, tempOutputWordLength, freqArray, wordLengthArray, outputWord); } @@ -668,7 +668,7 @@ void UnigramDictionary::getMultiWordsSuggestionRec(ProximityInfo *proximityInfo, AKLOGI("Do mistyped space correction"); } getSubStringSuggestion(proximityInfo, xcoordinates, ycoordinates, codes, - useFullEditDistance, correction, queuePool, inputLength, hasAutoCorrectionCandidate, + useFullEditDistance, correction, queuePool, inputSize, hasAutoCorrectionCandidate, startWordIndex + 1, inputWordStartPos, inputWordLength, tempOutputWordLength, true /* mistyped space */, freqArray, wordLengthArray, outputWord, 0); } @@ -676,10 +676,10 @@ void UnigramDictionary::getMultiWordsSuggestionRec(ProximityInfo *proximityInfo, void UnigramDictionary::getSplitMultipleWordsSuggestions(ProximityInfo *proximityInfo, const int *xcoordinates, const int *ycoordinates, const int *codes, - const bool useFullEditDistance, const int inputLength, + const bool useFullEditDistance, const int inputSize, Correction *correction, WordsPriorityQueuePool *queuePool, const bool hasAutoCorrectionCandidate) const { - if (inputLength >= MAX_WORD_LENGTH) return; + if (inputSize >= MAX_WORD_LENGTH) return; if (DEBUG_DICT) { AKLOGI("--- Suggest multiple words"); } @@ -692,7 +692,7 @@ void UnigramDictionary::getSplitMultipleWordsSuggestions(ProximityInfo *proximit const int startInputPos = 0; const int startWordIndex = 0; getMultiWordsSuggestionRec(proximityInfo, xcoordinates, ycoordinates, codes, - useFullEditDistance, inputLength, correction, queuePool, hasAutoCorrectionCandidate, + useFullEditDistance, inputSize, correction, queuePool, hasAutoCorrectionCandidate, startInputPos, startWordIndex, outputWordLength, freqArray, wordLengthArray, outputWord); } @@ -700,13 +700,13 @@ void UnigramDictionary::getSplitMultipleWordsSuggestions(ProximityInfo *proximit // Wrapper for getMostFrequentWordLikeInner, which matches it to the previous // interface. inline int UnigramDictionary::getMostFrequentWordLike(const int startInputIndex, - const int inputLength, Correction *correction, unsigned short *word) const { - uint16_t inWord[inputLength]; + const int inputSize, Correction *correction, unsigned short *word) const { + uint16_t inWord[inputSize]; - for (int i = 0; i < inputLength; ++i) { + for (int i = 0; i < inputSize; ++i) { inWord[i] = (uint16_t)correction->getPrimaryCharAt(startInputIndex + i); } - return getMostFrequentWordLikeInner(inWord, inputLength, word); + return getMostFrequentWordLikeInner(inWord, inputSize, word); } // This function will take the position of a character array within a CharGroup, diff --git a/native/jni/src/unigram_dictionary.h b/native/jni/src/unigram_dictionary.h index 6083f0175..2c6622210 100644 --- a/native/jni/src/unigram_dictionary.h +++ b/native/jni/src/unigram_dictionary.h @@ -53,7 +53,7 @@ class UnigramDictionary { private: DISALLOW_IMPLICIT_CONSTRUCTORS(UnigramDictionary); void getWordSuggestions(ProximityInfo *proximityInfo, const int *xcoordinates, - const int *ycoordinates, const int *codes, const int inputLength, + const int *ycoordinates, const int *codes, const int inputSize, const std::map<int, int> *bigramMap, const uint8_t *bigramFilter, const bool useFullEditDistance, Correction *correction, WordsPriorityQueuePool *queuePool) const; @@ -72,16 +72,16 @@ class UnigramDictionary { Correction *correction) const; void getOneWordSuggestions(ProximityInfo *proximityInfo, const int *xcoordinates, const int *ycoordinates, const int *codes, const std::map<int, int> *bigramMap, - const uint8_t *bigramFilter, const bool useFullEditDistance, const int inputLength, + const uint8_t *bigramFilter, const bool useFullEditDistance, const int inputSize, Correction *correction, WordsPriorityQueuePool *queuePool) const; void getSuggestionCandidates( - const bool useFullEditDistance, const int inputLength, + const bool useFullEditDistance, const int inputSize, const std::map<int, int> *bigramMap, const uint8_t *bigramFilter, Correction *correction, WordsPriorityQueuePool *queuePool, const bool doAutoCompletion, const int maxErrors, const int currentWordIndex) const; void getSplitMultipleWordsSuggestions(ProximityInfo *proximityInfo, const int *xcoordinates, const int *ycoordinates, const int *codes, - const bool useFullEditDistance, const int inputLength, + const bool useFullEditDistance, const int inputSize, Correction *correction, WordsPriorityQueuePool *queuePool, const bool hasAutoCorrectionCandidate) const; void onTerminal(const int freq, const TerminalAttributes& terminalAttributes, @@ -92,21 +92,21 @@ class UnigramDictionary { const uint8_t *bigramFilter, Correction *correction, int *newCount, int *newChildPosition, int *nextSiblingPosition, WordsPriorityQueuePool *queuePool, const int currentWordIndex) const; - int getMostFrequentWordLike(const int startInputIndex, const int inputLength, + int getMostFrequentWordLike(const int startInputIndex, const int inputSize, Correction *correction, unsigned short *word) const; int getMostFrequentWordLikeInner(const uint16_t *const inWord, const int length, short unsigned int *outWord) const; int getSubStringSuggestion( ProximityInfo *proximityInfo, const int *xcoordinates, const int *ycoordinates, const int *codes, const bool useFullEditDistance, Correction *correction, - WordsPriorityQueuePool *queuePool, const int inputLength, + WordsPriorityQueuePool *queuePool, const int inputSize, const bool hasAutoCorrectionCandidate, const int currentWordIndex, const int inputWordStartPos, const int inputWordLength, const int outputWordStartPos, const bool isSpaceProximity, int *freqArray, int *wordLengthArray, unsigned short *outputWord, int *outputWordLength) const; void getMultiWordsSuggestionRec(ProximityInfo *proximityInfo, const int *xcoordinates, const int *ycoordinates, const int *codes, - const bool useFullEditDistance, const int inputLength, + const bool useFullEditDistance, const int inputSize, Correction *correction, WordsPriorityQueuePool *queuePool, const bool hasAutoCorrectionCandidate, const int startPos, const int startWordIndex, const int outputWordLength, int *freqArray, int *wordLengthArray, |