diff options
Diffstat (limited to 'native/jni/src')
41 files changed, 519 insertions, 294 deletions
diff --git a/native/jni/src/bigram_dictionary.cpp b/native/jni/src/bigram_dictionary.cpp index 43e59a262..92890383a 100644 --- a/native/jni/src/bigram_dictionary.cpp +++ b/native/jni/src/bigram_dictionary.cpp @@ -39,7 +39,7 @@ BigramDictionary::~BigramDictionary() { void BigramDictionary::addWordBigram(int *word, int length, int probability, int *bigramProbability, int *bigramCodePoints, int *outputTypes) const { word[length] = 0; - if (DEBUG_DICT) { + if (DEBUG_DICT_FULL) { #ifdef FLAG_DBG char s[length + 1]; for (int i = 0; i <= length; i++) s[i] = static_cast<char>(word[i]); @@ -57,7 +57,7 @@ void BigramDictionary::addWordBigram(int *word, int length, int probability, int } insertAt++; } - if (DEBUG_DICT) { + if (DEBUG_DICT_FULL) { AKLOGI("Bigram: InsertAt -> %d MAX_RESULTS: %d", insertAt, MAX_RESULTS); } if (insertAt >= MAX_RESULTS) { @@ -76,7 +76,7 @@ void BigramDictionary::addWordBigram(int *word, int length, int probability, int *dest++ = *word++; } *dest = 0; // NULL terminate - if (DEBUG_DICT) { + if (DEBUG_DICT_FULL) { AKLOGI("Bigram: Added word at %d", insertAt); } } diff --git a/native/jni/src/correction.cpp b/native/jni/src/correction.cpp index 671507ee0..76234f840 100644 --- a/native/jni/src/correction.cpp +++ b/native/jni/src/correction.cpp @@ -954,7 +954,13 @@ inline static int editDistanceInternal(int *editDistanceTable, const int *before // In dictionary.cpp, getSuggestion() method, -// suggestion scores are computed using the below formula. +// When USE_SUGGEST_INTERFACE_FOR_TYPING is true: +// SUGGEST_INTERFACE_OUTPUT_SCALE was multiplied to the original suggestion scores to convert +// them to integers. +// score = (int)((original score) * SUGGEST_INTERFACE_OUTPUT_SCALE) +// Undo the scaling here to recover the original score. +// normalizedScore = ((float)score) / SUGGEST_INTERFACE_OUTPUT_SCALE +// Otherwise: suggestion scores are computed using the below formula. // original score // := powf(mTypedLetterMultiplier (this is defined 2), // (the number of matched characters between typed word and suggested word)) @@ -991,16 +997,20 @@ inline static int editDistanceInternal(int *editDistanceTable, const int *before return 0.0f; } + // add a weight based on edit distance. + // distance <= max(afterLength, beforeLength) == afterLength, + // so, 0 <= distance / afterLength <= 1 + const float weight = 1.0f - static_cast<float>(distance) / static_cast<float>(afterLength); + + if (USE_SUGGEST_INTERFACE_FOR_TYPING) { + return (static_cast<float>(score) / SUGGEST_INTERFACE_OUTPUT_SCALE) * weight; + } const float maxScore = score >= S_INT_MAX ? static_cast<float>(S_INT_MAX) : static_cast<float>(MAX_INITIAL_SCORE) * powf(static_cast<float>(TYPED_LETTER_MULTIPLIER), static_cast<float>(min(beforeLength, afterLength - spaceCount))) * static_cast<float>(FULL_WORD_MULTIPLIER); - // add a weight based on edit distance. - // distance <= max(afterLength, beforeLength) == afterLength, - // so, 0 <= distance / afterLength <= 1 - const float weight = 1.0f - static_cast<float>(distance) / static_cast<float>(afterLength); return (static_cast<float>(score) / maxScore) * weight; } } // namespace latinime diff --git a/native/jni/src/defines.h b/native/jni/src/defines.h index 6e098157d..a45691261 100644 --- a/native/jni/src/defines.h +++ b/native/jni/src/defines.h @@ -287,6 +287,7 @@ static inline void prof_out(void) { #define CALIBRATE_SCORE_BY_TOUCH_COORDINATES true #define SUGGEST_MULTIPLE_WORDS true +#define USE_SUGGEST_INTERFACE_FOR_TYPING true #define SUGGEST_INTERFACE_OUTPUT_SCALE 1000000.0f // The following "rate"s are used as a multiplier before dividing by 100, so they are in percent. diff --git a/native/jni/src/dictionary.cpp b/native/jni/src/dictionary.cpp index 6deab36b6..c998c0676 100644 --- a/native/jni/src/dictionary.cpp +++ b/native/jni/src/dictionary.cpp @@ -16,14 +16,18 @@ #define LOG_TAG "LatinIME: dictionary.cpp" +#include "dictionary.h" + +#include <map> // TODO: remove #include <stdint.h> #include "bigram_dictionary.h" #include "binary_format.h" #include "defines.h" -#include "dictionary.h" #include "dic_traverse_wrapper.h" -#include "gesture_suggest.h" +#include "suggest/core/suggest.h" +#include "suggest/policyimpl/gesture/gesture_suggest_policy_factory.h" +#include "suggest/policyimpl/typing/typing_suggest_policy_factory.h" #include "unigram_dictionary.h" namespace latinime { @@ -34,13 +38,15 @@ Dictionary::Dictionary(void *dict, int dictSize, int mmapFd, int dictBufAdjust) mDictSize(dictSize), mMmapFd(mmapFd), mDictBufAdjust(dictBufAdjust), mUnigramDictionary(new UnigramDictionary(mOffsetDict, BinaryFormat::getFlags(mDict))), mBigramDictionary(new BigramDictionary(mOffsetDict)), - mGestureSuggest(new GestureSuggest()) { + mGestureSuggest(new Suggest(GestureSuggestPolicyFactory::getGestureSuggestPolicy())), + mTypingSuggest(new Suggest(TypingSuggestPolicyFactory::getTypingSuggestPolicy())) { } Dictionary::~Dictionary() { delete mUnigramDictionary; delete mBigramDictionary; delete mGestureSuggest; + delete mTypingSuggest; } int Dictionary::getSuggestions(ProximityInfo *proximityInfo, void *traverseSession, @@ -60,14 +66,26 @@ int Dictionary::getSuggestions(ProximityInfo *proximityInfo, void *traverseSessi } return result; } else { - std::map<int, int> bigramMap; - uint8_t bigramFilter[BIGRAM_FILTER_BYTE_SIZE]; - mBigramDictionary->fillBigramAddressToProbabilityMapAndFilter(prevWordCodePoints, - prevWordLength, &bigramMap, bigramFilter); - result = mUnigramDictionary->getSuggestions(proximityInfo, xcoordinates, ycoordinates, - inputCodePoints, inputSize, &bigramMap, bigramFilter, useFullEditDistance, outWords, - frequencies, outputTypes); - return result; + if (USE_SUGGEST_INTERFACE_FOR_TYPING) { + DicTraverseWrapper::initDicTraverseSession( + traverseSession, this, prevWordCodePoints, prevWordLength); + result = mTypingSuggest->getSuggestions(proximityInfo, traverseSession, xcoordinates, + ycoordinates, times, pointerIds, inputCodePoints, inputSize, commitPoint, + outWords, frequencies, spaceIndices, outputTypes); + if (DEBUG_DICT) { + DUMP_RESULT(outWords, frequencies); + } + return result; + } else { + std::map<int, int> bigramMap; + uint8_t bigramFilter[BIGRAM_FILTER_BYTE_SIZE]; + mBigramDictionary->fillBigramAddressToProbabilityMapAndFilter(prevWordCodePoints, + prevWordLength, &bigramMap, bigramFilter); + result = mUnigramDictionary->getSuggestions(proximityInfo, xcoordinates, ycoordinates, + inputCodePoints, inputSize, &bigramMap, bigramFilter, useFullEditDistance, + outWords, frequencies, outputTypes); + return result; + } } } @@ -85,4 +103,9 @@ int Dictionary::getProbability(const int *word, int length) const { bool Dictionary::isValidBigram(const int *word1, int length1, const int *word2, int length2) const { return mBigramDictionary->isValidBigram(word1, length1, word2, length2); } + +int Dictionary::getDictFlags() const { + return mUnigramDictionary->getDictFlags(); +} + } // namespace latinime diff --git a/native/jni/src/dictionary.h b/native/jni/src/dictionary.h index 449b95ab6..0653d3ca9 100644 --- a/native/jni/src/dictionary.h +++ b/native/jni/src/dictionary.h @@ -63,6 +63,7 @@ class Dictionary { int getDictSize() const { return mDictSize; } int getMmapFd() const { return mMmapFd; } int getDictBufAdjust() const { return mDictBufAdjust; } + int getDictFlags() const; virtual ~Dictionary(); private: @@ -79,6 +80,7 @@ class Dictionary { const UnigramDictionary *mUnigramDictionary; const BigramDictionary *mBigramDictionary; SuggestInterface *mGestureSuggest; + SuggestInterface *mTypingSuggest; }; } // namespace latinime #endif // LATINIME_DICTIONARY_H diff --git a/native/jni/src/digraph_utils.cpp b/native/jni/src/digraph_utils.cpp new file mode 100644 index 000000000..6a1ab0271 --- /dev/null +++ b/native/jni/src/digraph_utils.cpp @@ -0,0 +1,133 @@ +/* + * Copyright (C) 2013 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "binary_format.h" +#include "defines.h" +#include "digraph_utils.h" + +namespace latinime { + +const DigraphUtils::digraph_t DigraphUtils::GERMAN_UMLAUT_DIGRAPHS[] = + { { 'a', 'e', 0x00E4 }, // U+00E4 : LATIN SMALL LETTER A WITH DIAERESIS + { 'o', 'e', 0x00F6 }, // U+00F6 : LATIN SMALL LETTER O WITH DIAERESIS + { 'u', 'e', 0x00FC } }; // U+00FC : LATIN SMALL LETTER U WITH DIAERESIS +const DigraphUtils::digraph_t DigraphUtils::FRENCH_LIGATURES_DIGRAPHS[] = + { { 'a', 'e', 0x00E6 }, // U+00E6 : LATIN SMALL LETTER AE + { 'o', 'e', 0x0153 } }; // U+0153 : LATIN SMALL LIGATURE OE +const DigraphUtils::DigraphType DigraphUtils::USED_DIGRAPH_TYPES[] = + { DIGRAPH_TYPE_GERMAN_UMLAUT, DIGRAPH_TYPE_FRENCH_LIGATURES }; + +/* static */ bool DigraphUtils::hasDigraphForCodePoint( + const int dictFlags, const int compositeGlyphCodePoint) { + const DigraphUtils::DigraphType digraphType = getDigraphTypeForDictionary(dictFlags); + if (DigraphUtils::getDigraphForDigraphTypeAndCodePoint(digraphType, compositeGlyphCodePoint)) { + return true; + } + return false; +} + +// Returns the digraph type associated with the given dictionary. +/* static */ DigraphUtils::DigraphType DigraphUtils::getDigraphTypeForDictionary( + const int dictFlags) { + if (BinaryFormat::REQUIRES_GERMAN_UMLAUT_PROCESSING & dictFlags) { + return DIGRAPH_TYPE_GERMAN_UMLAUT; + } + if (BinaryFormat::REQUIRES_FRENCH_LIGATURES_PROCESSING & dictFlags) { + return DIGRAPH_TYPE_FRENCH_LIGATURES; + } + return DIGRAPH_TYPE_NONE; +} + +// Retrieves the set of all digraphs associated with the given dictionary flags. +// Returns the size of the digraph array, or 0 if none exist. +/* static */ int DigraphUtils::getAllDigraphsForDictionaryAndReturnSize( + const int dictFlags, const DigraphUtils::digraph_t **const digraphs) { + const DigraphUtils::DigraphType digraphType = getDigraphTypeForDictionary(dictFlags); + return getAllDigraphsForDigraphTypeAndReturnSize(digraphType, digraphs); +} + +// Returns the digraph codepoint for the given composite glyph codepoint and digraph codepoint index +// (which specifies the first or second codepoint in the digraph). +/* static */ int DigraphUtils::getDigraphCodePointForIndex(const int compositeGlyphCodePoint, + const DigraphCodePointIndex digraphCodePointIndex) { + if (digraphCodePointIndex == NOT_A_DIGRAPH_INDEX) { + return NOT_A_CODE_POINT; + } + const DigraphUtils::digraph_t *const digraph = + DigraphUtils::getDigraphForCodePoint(compositeGlyphCodePoint); + if (!digraph) { + return NOT_A_CODE_POINT; + } + if (digraphCodePointIndex == FIRST_DIGRAPH_CODEPOINT) { + return digraph->first; + } else if (digraphCodePointIndex == SECOND_DIGRAPH_CODEPOINT) { + return digraph->second; + } + ASSERT(false); + return NOT_A_CODE_POINT; +} + +// Retrieves the set of all digraphs associated with the given digraph type. +// Returns the size of the digraph array, or 0 if none exist. +/* static */ int DigraphUtils::getAllDigraphsForDigraphTypeAndReturnSize( + const DigraphUtils::DigraphType digraphType, + const DigraphUtils::digraph_t **const digraphs) { + if (digraphType == DigraphUtils::DIGRAPH_TYPE_GERMAN_UMLAUT) { + *digraphs = GERMAN_UMLAUT_DIGRAPHS; + return NELEMS(GERMAN_UMLAUT_DIGRAPHS); + } + if (digraphType == DIGRAPH_TYPE_FRENCH_LIGATURES) { + *digraphs = FRENCH_LIGATURES_DIGRAPHS; + return NELEMS(FRENCH_LIGATURES_DIGRAPHS); + } + return 0; +} + +/** + * Returns the digraph for the input composite glyph codepoint, or 0 if none exists. + * compositeGlyphCodePoint: the method returns the digraph corresponding to this codepoint. + */ +/* static */ const DigraphUtils::digraph_t *DigraphUtils::getDigraphForCodePoint( + const int compositeGlyphCodePoint) { + for (size_t i = 0; i < NELEMS(USED_DIGRAPH_TYPES); i++) { + const DigraphUtils::digraph_t *const digraph = getDigraphForDigraphTypeAndCodePoint( + USED_DIGRAPH_TYPES[i], compositeGlyphCodePoint); + if (digraph) { + return digraph; + } + } + return 0; +} + +/** + * Returns the digraph for the input composite glyph codepoint, or 0 if none exists. + * digraphType: the type of digraphs supported. + * compositeGlyphCodePoint: the method returns the digraph corresponding to this codepoint. + */ +/* static */ const DigraphUtils::digraph_t *DigraphUtils::getDigraphForDigraphTypeAndCodePoint( + const DigraphUtils::DigraphType digraphType, const int compositeGlyphCodePoint) { + const DigraphUtils::digraph_t *digraphs = 0; + const int digraphsSize = + DigraphUtils::getAllDigraphsForDictionaryAndReturnSize(digraphType, &digraphs); + for (int i = 0; i < digraphsSize; i++) { + if (digraphs[i].compositeGlyph == compositeGlyphCodePoint) { + return &digraphs[i]; + } + } + return 0; +} + +} // namespace latinime diff --git a/native/jni/src/digraph_utils.h b/native/jni/src/digraph_utils.h new file mode 100644 index 000000000..94435228e --- /dev/null +++ b/native/jni/src/digraph_utils.h @@ -0,0 +1,60 @@ +/* + * Copyright (C) 2013 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef DIGRAPH_UTILS_H +#define DIGRAPH_UTILS_H + +namespace latinime { + +class DigraphUtils { + public: + typedef enum { + NOT_A_DIGRAPH_INDEX, + FIRST_DIGRAPH_CODEPOINT, + SECOND_DIGRAPH_CODEPOINT + } DigraphCodePointIndex; + + typedef enum { + DIGRAPH_TYPE_NONE, + DIGRAPH_TYPE_GERMAN_UMLAUT, + DIGRAPH_TYPE_FRENCH_LIGATURES + } DigraphType; + + typedef struct { int first; int second; int compositeGlyph; } digraph_t; + + static bool hasDigraphForCodePoint(const int dictFlags, const int compositeGlyphCodePoint); + static int getAllDigraphsForDictionaryAndReturnSize( + const int dictFlags, const digraph_t **const digraphs); + static int getDigraphCodePointForIndex(const int dictFlags, const int compositeGlyphCodePoint, + const DigraphCodePointIndex digraphCodePointIndex); + static int getDigraphCodePointForIndex(const int compositeGlyphCodePoint, + const DigraphCodePointIndex digraphCodePointIndex); + + private: + DISALLOW_IMPLICIT_CONSTRUCTORS(DigraphUtils); + static DigraphType getDigraphTypeForDictionary(const int dictFlags); + static int getAllDigraphsForDigraphTypeAndReturnSize( + const DigraphType digraphType, const digraph_t **const digraphs); + static const digraph_t *getDigraphForCodePoint(const int compositeGlyphCodePoint); + static const digraph_t *getDigraphForDigraphTypeAndCodePoint( + const DigraphType digraphType, const int compositeGlyphCodePoint); + + static const digraph_t GERMAN_UMLAUT_DIGRAPHS[]; + static const digraph_t FRENCH_LIGATURES_DIGRAPHS[]; + static const DigraphType USED_DIGRAPH_TYPES[]; +}; +} // namespace latinime +#endif // DIGRAPH_UTILS_H diff --git a/native/jni/src/proximity_info.cpp b/native/jni/src/proximity_info.cpp index 74b5e0131..88d670d61 100644 --- a/native/jni/src/proximity_info.cpp +++ b/native/jni/src/proximity_info.cpp @@ -49,13 +49,17 @@ static AK_FORCE_INLINE void safeGetOrFillZeroFloatArrayRegion(JNIEnv *env, jfloa ProximityInfo::ProximityInfo(JNIEnv *env, const jstring localeJStr, const int keyboardWidth, const int keyboardHeight, const int gridWidth, - const int gridHeight, const int mostCommonKeyWidth, const jintArray proximityChars, - const int keyCount, const jintArray keyXCoordinates, const jintArray keyYCoordinates, - const jintArray keyWidths, const jintArray keyHeights, const jintArray keyCharCodes, - const jfloatArray sweetSpotCenterXs, const jfloatArray sweetSpotCenterYs, - const jfloatArray sweetSpotRadii) + const int gridHeight, const int mostCommonKeyWidth, const int mostCommonKeyHeight, + const jintArray proximityChars, const int keyCount, const jintArray keyXCoordinates, + const jintArray keyYCoordinates, const jintArray keyWidths, const jintArray keyHeights, + const jintArray keyCharCodes, const jfloatArray sweetSpotCenterXs, + const jfloatArray sweetSpotCenterYs, const jfloatArray sweetSpotRadii) : GRID_WIDTH(gridWidth), GRID_HEIGHT(gridHeight), MOST_COMMON_KEY_WIDTH(mostCommonKeyWidth), MOST_COMMON_KEY_WIDTH_SQUARE(mostCommonKeyWidth * mostCommonKeyWidth), + MOST_COMMON_KEY_HEIGHT(mostCommonKeyHeight), + NORMALIZED_SQUARED_MOST_COMMON_KEY_HYPOTENUSE(1.0f + + SQUARE_FLOAT(static_cast<float>(mostCommonKeyHeight) / + static_cast<float>(mostCommonKeyWidth))), CELL_WIDTH((keyboardWidth + gridWidth - 1) / gridWidth), CELL_HEIGHT((keyboardHeight + gridHeight - 1) / gridHeight), KEY_COUNT(min(keyCount, MAX_KEY_COUNT_IN_A_KEYBOARD)), @@ -129,7 +133,7 @@ bool ProximityInfo::hasSpaceProximity(const int x, const int y) const { } float ProximityInfo::getNormalizedSquaredDistanceFromCenterFloatG( - const int keyId, const int x, const int y) const { + const int keyId, const int x, const int y, const float verticalScale) const { const bool correctTouchPosition = hasTouchPositionCorrectionData(); const float centerX = static_cast<float>(correctTouchPosition ? getSweetSpotCenterXAt(keyId) : getKeyCenterXOfKeyIdG(keyId)); @@ -138,7 +142,7 @@ float ProximityInfo::getNormalizedSquaredDistanceFromCenterFloatG( if (correctTouchPosition) { const float sweetSpotCenterY = static_cast<float>(getSweetSpotCenterYAt(keyId)); const float gapY = sweetSpotCenterY - visualKeyCenterY; - centerY = visualKeyCenterY + gapY * ProximityInfoParams::VERTICAL_SWEET_SPOT_SCALE_G; + centerY = visualKeyCenterY + gapY * verticalScale; } else { centerY = visualKeyCenterY; } diff --git a/native/jni/src/proximity_info.h b/native/jni/src/proximity_info.h index 57a175d2c..deb9ae0de 100644 --- a/native/jni/src/proximity_info.h +++ b/native/jni/src/proximity_info.h @@ -30,16 +30,17 @@ class ProximityInfo { public: ProximityInfo(JNIEnv *env, const jstring localeJStr, const int keyboardWidth, const int keyboardHeight, const int gridWidth, - const int gridHeight, const int mostCommonKeyWidth, const jintArray proximityChars, - const int keyCount, const jintArray keyXCoordinates, const jintArray keyYCoordinates, - const jintArray keyWidths, const jintArray keyHeights, const jintArray keyCharCodes, - const jfloatArray sweetSpotCenterXs, const jfloatArray sweetSpotCenterYs, - const jfloatArray sweetSpotRadii); + const int gridHeight, const int mostCommonKeyWidth, const int mostCommonKeyHeight, + const jintArray proximityChars, const int keyCount, const jintArray keyXCoordinates, + const jintArray keyYCoordinates, const jintArray keyWidths, const jintArray keyHeights, + const jintArray keyCharCodes, const jfloatArray sweetSpotCenterXs, + const jfloatArray sweetSpotCenterYs, const jfloatArray sweetSpotRadii); ~ProximityInfo(); bool hasSpaceProximity(const int x, const int y) const; int getNormalizedSquaredDistance(const int inputIndex, const int proximityIndex) const; float getNormalizedSquaredDistanceFromCenterFloatG( - const int keyId, const int x, const int y) const; + const int keyId, const int x, const int y, + const float verticalScale) const; bool sameAsTyped(const unsigned short *word, int length) const; int getCodePointOf(const int keyIndex) const; bool hasSweetSpotData(const int keyIndex) const { @@ -55,6 +56,9 @@ class ProximityInfo { bool hasTouchPositionCorrectionData() const { return HAS_TOUCH_POSITION_CORRECTION_DATA; } int getMostCommonKeyWidth() const { return MOST_COMMON_KEY_WIDTH; } int getMostCommonKeyWidthSquare() const { return MOST_COMMON_KEY_WIDTH_SQUARE; } + float getNormalizedSquaredMostCommonKeyHypotenuse() const { + return NORMALIZED_SQUARED_MOST_COMMON_KEY_HYPOTENUSE; + } int getKeyCount() const { return KEY_COUNT; } int getCellHeight() const { return CELL_HEIGHT; } int getCellWidth() const { return CELL_WIDTH; } @@ -98,6 +102,8 @@ class ProximityInfo { const int GRID_HEIGHT; const int MOST_COMMON_KEY_WIDTH; const int MOST_COMMON_KEY_WIDTH_SQUARE; + const int MOST_COMMON_KEY_HEIGHT; + const float NORMALIZED_SQUARED_MOST_COMMON_KEY_HYPOTENUSE; const int CELL_WIDTH; const int CELL_HEIGHT; const int KEY_COUNT; diff --git a/native/jni/src/proximity_info_params.cpp b/native/jni/src/proximity_info_params.cpp index f9a4352ee..2675d9e70 100644 --- a/native/jni/src/proximity_info_params.cpp +++ b/native/jni/src/proximity_info_params.cpp @@ -20,7 +20,8 @@ namespace latinime { const float ProximityInfoParams::NOT_A_DISTANCE_FLOAT = -1.0f; const int ProximityInfoParams::MIN_DOUBLE_LETTER_BEELINE_SPEED_PERCENTILE = 5; -const float ProximityInfoParams::VERTICAL_SWEET_SPOT_SCALE_G = 1.1f; +const float ProximityInfoParams::VERTICAL_SWEET_SPOT_SCALE = 1.0f; +const float ProximityInfoParams::VERTICAL_SWEET_SPOT_SCALE_G = 0.5f; /* Per method constants */ // Used by ProximityInfoStateUtils::initGeometricDistanceInfos() diff --git a/native/jni/src/proximity_info_params.h b/native/jni/src/proximity_info_params.h index e7aec0976..4e47f7308 100644 --- a/native/jni/src/proximity_info_params.h +++ b/native/jni/src/proximity_info_params.h @@ -25,6 +25,7 @@ class ProximityInfoParams { public: static const float NOT_A_DISTANCE_FLOAT; static const int MIN_DOUBLE_LETTER_BEELINE_SPEED_PERCENTILE; + static const float VERTICAL_SWEET_SPOT_SCALE; static const float VERTICAL_SWEET_SPOT_SCALE_G; // Used by ProximityInfoStateUtils::initGeometricDistanceInfos() diff --git a/native/jni/src/proximity_info_state.cpp b/native/jni/src/proximity_info_state.cpp index 861ba9971..a10b260e1 100644 --- a/native/jni/src/proximity_info_state.cpp +++ b/native/jni/src/proximity_info_state.cpp @@ -28,6 +28,7 @@ namespace latinime { +// TODO: Remove the dependency of "isGeometric" void ProximityInfoState::initInputParams(const int pointerId, const float maxPointToKeyLength, const ProximityInfo *proximityInfo, const int *const inputCodes, const int inputSize, const int *const xCoordinates, const int *const yCoordinates, const int *const times, @@ -94,12 +95,17 @@ void ProximityInfoState::initInputParams(const int pointerId, const float maxPoi pushTouchPointStartIndex, lastSavedInputSize); } + // TODO: Remove the dependency of "isGeometric" + const float verticalSweetSpotScale = isGeometric + ? ProximityInfoParams::VERTICAL_SWEET_SPOT_SCALE_G + : ProximityInfoParams::VERTICAL_SWEET_SPOT_SCALE; + if (xCoordinates && yCoordinates) { mSampledInputSize = ProximityInfoStateUtils::updateTouchPoints(mProximityInfo, mMaxPointToKeyLength, mInputProximities, xCoordinates, yCoordinates, times, - pointerIds, inputSize, isGeometric, pointerId, pushTouchPointStartIndex, - &mSampledInputXs, &mSampledInputYs, &mSampledTimes, &mSampledLengthCache, - &mSampledInputIndice); + pointerIds, verticalSweetSpotScale, inputSize, isGeometric, pointerId, + pushTouchPointStartIndex, &mSampledInputXs, &mSampledInputYs, &mSampledTimes, + &mSampledLengthCache, &mSampledInputIndice); } if (mSampledInputSize > 0 && isGeometric) { @@ -115,8 +121,8 @@ void ProximityInfoState::initInputParams(const int pointerId, const float maxPoi if (mSampledInputSize > 0) { ProximityInfoStateUtils::initGeometricDistanceInfos(mProximityInfo, mSampledInputSize, - lastSavedInputSize, &mSampledInputXs, &mSampledInputYs, &mSampledNearKeySets, - &mSampledDistanceCache_G); + lastSavedInputSize, verticalSweetSpotScale, &mSampledInputXs, &mSampledInputYs, + &mSampledNearKeySets, &mSampledDistanceCache_G); if (isGeometric) { // updates probabilities of skipping or mapping each key for all points. ProximityInfoStateUtils::updateAlignPointProbabilities( diff --git a/native/jni/src/proximity_info_state_utils.cpp b/native/jni/src/proximity_info_state_utils.cpp index 760508076..df70cffdf 100644 --- a/native/jni/src/proximity_info_state_utils.cpp +++ b/native/jni/src/proximity_info_state_utils.cpp @@ -42,8 +42,8 @@ namespace latinime { const ProximityInfo *const proximityInfo, const int maxPointToKeyLength, const int *const inputProximities, const int *const inputXCoordinates, const int *const inputYCoordinates, const int *const times, const int *const pointerIds, - const int inputSize, const bool isGeometric, const int pointerId, - const int pushTouchPointStartIndex, std::vector<int> *sampledInputXs, + const float verticalSweetSpotScale, const int inputSize, const bool isGeometric, + const int pointerId, const int pushTouchPointStartIndex, std::vector<int> *sampledInputXs, std::vector<int> *sampledInputYs, std::vector<int> *sampledInputTimes, std::vector<int> *sampledLengthCache, std::vector<int> *sampledInputIndice) { if (DEBUG_SAMPLING_POINTS) { @@ -112,10 +112,10 @@ namespace latinime { } if (pushTouchPoint(proximityInfo, maxPointToKeyLength, i, c, x, y, time, - isGeometric /* doSampling */, i == lastInputIndex, sumAngle, - currentNearKeysDistances, prevNearKeysDistances, prevPrevNearKeysDistances, - sampledInputXs, sampledInputYs, sampledInputTimes, sampledLengthCache, - sampledInputIndice)) { + verticalSweetSpotScale, isGeometric /* doSampling */, i == lastInputIndex, + sumAngle, currentNearKeysDistances, prevNearKeysDistances, + prevPrevNearKeysDistances, sampledInputXs, sampledInputYs, sampledInputTimes, + sampledLengthCache, sampledInputIndice)) { // Previous point information was popped. NearKeysDistanceMap *tmp = prevNearKeysDistances; prevNearKeysDistances = currentNearKeysDistances; @@ -222,7 +222,8 @@ namespace latinime { /* static */ void ProximityInfoStateUtils::initGeometricDistanceInfos( const ProximityInfo *const proximityInfo, const int sampledInputSize, - const int lastSavedInputSize, const std::vector<int> *const sampledInputXs, + const int lastSavedInputSize, const float verticalSweetSpotScale, + const std::vector<int> *const sampledInputXs, const std::vector<int> *const sampledInputYs, std::vector<NearKeycodesSet> *SampledNearKeySets, std::vector<float> *SampledDistanceCache_G) { @@ -236,7 +237,8 @@ namespace latinime { const int x = (*sampledInputXs)[i]; const int y = (*sampledInputYs)[i]; const float normalizedSquaredDistance = - proximityInfo->getNormalizedSquaredDistanceFromCenterFloatG(k, x, y); + proximityInfo->getNormalizedSquaredDistanceFromCenterFloatG( + k, x, y, verticalSweetSpotScale); (*SampledDistanceCache_G)[index] = normalizedSquaredDistance; if (normalizedSquaredDistance < ProximityInfoParams::NEAR_KEY_NORMALIZED_SQUARED_THRESHOLD) { @@ -354,12 +356,14 @@ namespace latinime { // the given point and the nearest key position. /* static */ float ProximityInfoStateUtils::updateNearKeysDistances( const ProximityInfo *const proximityInfo, const float maxPointToKeyLength, const int x, - const int y, NearKeysDistanceMap *const currentNearKeysDistances) { + const int y, const float verticalSweetspotScale, + NearKeysDistanceMap *const currentNearKeysDistances) { currentNearKeysDistances->clear(); const int keyCount = proximityInfo->getKeyCount(); float nearestKeyDistance = maxPointToKeyLength; for (int k = 0; k < keyCount; ++k) { - const float dist = proximityInfo->getNormalizedSquaredDistanceFromCenterFloatG(k, x, y); + const float dist = proximityInfo->getNormalizedSquaredDistanceFromCenterFloatG(k, x, y, + verticalSweetspotScale); if (dist < ProximityInfoParams::NEAR_KEY_THRESHOLD_FOR_DISTANCE) { currentNearKeysDistances->insert(std::pair<int, float>(k, dist)); } @@ -439,7 +443,8 @@ namespace latinime { // Returning if previous point is popped or not. /* static */ bool ProximityInfoStateUtils::pushTouchPoint(const ProximityInfo *const proximityInfo, const int maxPointToKeyLength, const int inputIndex, const int nodeCodePoint, int x, int y, - const int time, const bool doSampling, const bool isLastPoint, const float sumAngle, + const int time, const float verticalSweetSpotScale, const bool doSampling, + const bool isLastPoint, const float sumAngle, NearKeysDistanceMap *const currentNearKeysDistances, const NearKeysDistanceMap *const prevNearKeysDistances, const NearKeysDistanceMap *const prevPrevNearKeysDistances, @@ -451,8 +456,8 @@ namespace latinime { size_t size = sampledInputXs->size(); bool popped = false; if (nodeCodePoint < 0 && doSampling) { - const float nearest = updateNearKeysDistances( - proximityInfo, maxPointToKeyLength, x, y, currentNearKeysDistances); + const float nearest = updateNearKeysDistances(proximityInfo, maxPointToKeyLength, x, y, + verticalSweetSpotScale, currentNearKeysDistances); const float score = getPointScore(mostCommonKeyWidth, x, y, time, isLastPoint, nearest, sumAngle, currentNearKeysDistances, prevNearKeysDistances, prevPrevNearKeysDistances, sampledInputXs, sampledInputYs); diff --git a/native/jni/src/proximity_info_state_utils.h b/native/jni/src/proximity_info_state_utils.h index 3ceb25d8b..c9feb59a3 100644 --- a/native/jni/src/proximity_info_state_utils.h +++ b/native/jni/src/proximity_info_state_utils.h @@ -38,7 +38,8 @@ class ProximityInfoStateUtils { static int updateTouchPoints(const ProximityInfo *const proximityInfo, const int maxPointToKeyLength, const int *const inputProximities, const int *const inputXCoordinates, const int *const inputYCoordinates, - const int *const times, const int *const pointerIds, const int inputSize, + const int *const times, const int *const pointerIds, + const float verticalSweetSpotScale, const int inputSize, const bool isGeometric, const int pointerId, const int pushTouchPointStartIndex, std::vector<int> *sampledInputXs, std::vector<int> *sampledInputYs, std::vector<int> *sampledInputTimes, std::vector<int> *sampledLengthCache, @@ -84,6 +85,7 @@ class ProximityInfoStateUtils { const int inputIndex, const int keyId); static void initGeometricDistanceInfos(const ProximityInfo *const proximityInfo, const int sampledInputSize, const int lastSavedInputSize, + const float verticalSweetSpotScale, const std::vector<int> *const sampledInputXs, const std::vector<int> *const sampledInputYs, std::vector<NearKeycodesSet> *SampledNearKeySets, @@ -118,6 +120,7 @@ class ProximityInfoStateUtils { static float updateNearKeysDistances(const ProximityInfo *const proximityInfo, const float maxPointToKeyLength, const int x, const int y, + const float verticalSweetSpotScale, NearKeysDistanceMap *const currentNearKeysDistances); static bool isPrevLocalMin(const NearKeysDistanceMap *const currentNearKeysDistances, const NearKeysDistanceMap *const prevNearKeysDistances, @@ -130,7 +133,8 @@ class ProximityInfoStateUtils { std::vector<int> *sampledInputXs, std::vector<int> *sampledInputYs); static bool pushTouchPoint(const ProximityInfo *const proximityInfo, const int maxPointToKeyLength, const int inputIndex, const int nodeCodePoint, int x, - int y, const int time, const bool doSampling, const bool isLastPoint, + int y, const int time, const float verticalSweetSpotScale, + const bool doSampling, const bool isLastPoint, const float sumAngle, NearKeysDistanceMap *const currentNearKeysDistances, const NearKeysDistanceMap *const prevNearKeysDistances, const NearKeysDistanceMap *const prevPrevNearKeysDistances, diff --git a/native/jni/src/suggest/core/dicnode/dic_node.h b/native/jni/src/suggest/core/dicnode/dic_node.h index 7bfa459a2..32faae52c 100644 --- a/native/jni/src/suggest/core/dicnode/dic_node.h +++ b/native/jni/src/suggest/core/dicnode/dic_node.h @@ -23,6 +23,7 @@ #include "dic_node_profiler.h" #include "dic_node_properties.h" #include "dic_node_release_listener.h" +#include "digraph_utils.h" #if DEBUG_DICT #define LOGI_SHOW_ADD_COST_PROP \ @@ -48,13 +49,6 @@ namespace latinime { -// Naming convention -// - Distance: "Weighted" edit distance -- used both for spatial and language. -// - Compound Distance: Spatial Distance + Language Distance -- used for pruning and scoring -// - Cost: delta/diff for Distance -- used both for spatial and language -// - Length: "Non-weighted" -- used only for spatial -// - Probability: "Non-weighted" -- used only for language - // This struct is purely a bucket to return values. No instances of this struct should be kept. struct DicNode_InputStateG { bool mNeedsToUpdateInputStateG; @@ -406,8 +400,15 @@ class DicNode { // TODO: Remove // ////////////////////// // TODO: Remove once touch path is merged into ProximityInfoState + // Note: Returned codepoint may be a digraph codepoint if the node is in a composite glyph. int getNodeCodePoint() const { - return mDicNodeProperties.getNodeCodePoint(); + const int codePoint = mDicNodeProperties.getNodeCodePoint(); + const DigraphUtils::DigraphCodePointIndex digraphIndex = + mDicNodeState.mDicNodeStateScoring.getDigraphIndex(); + if (digraphIndex == DigraphUtils::NOT_A_DIGRAPH_INDEX) { + return codePoint; + } + return DigraphUtils::getDigraphCodePointForIndex(codePoint, digraphIndex); } //////////////////////////////// @@ -459,6 +460,15 @@ class DicNode { mDicNodeState.mDicNodeStateScoring.setDoubleLetterLevel(doubleLetterLevel); } + bool isInDigraph() const { + return mDicNodeState.mDicNodeStateScoring.getDigraphIndex() + != DigraphUtils::NOT_A_DIGRAPH_INDEX; + } + + void advanceDigraphIndex() { + mDicNodeState.mDicNodeStateScoring.advanceDigraphIndex(); + } + uint8_t getFlags() const { return mDicNodeProperties.getFlags(); } diff --git a/native/jni/src/suggest/core/dicnode/dic_node_state_scoring.h b/native/jni/src/suggest/core/dicnode/dic_node_state_scoring.h index 8e816329f..8902d3122 100644 --- a/native/jni/src/suggest/core/dicnode/dic_node_state_scoring.h +++ b/native/jni/src/suggest/core/dicnode/dic_node_state_scoring.h @@ -20,6 +20,7 @@ #include <stdint.h> #include "defines.h" +#include "digraph_utils.h" namespace latinime { @@ -27,6 +28,7 @@ class DicNodeStateScoring { public: AK_FORCE_INLINE DicNodeStateScoring() : mDoubleLetterLevel(NOT_A_DOUBLE_LETTER), + mDigraphIndex(DigraphUtils::NOT_A_DIGRAPH_INDEX), mEditCorrectionCount(0), mProximityCorrectionCount(0), mNormalizedCompoundDistance(0.0f), mSpatialDistance(0.0f), mLanguageDistance(0.0f), mTotalPrevWordsLanguageCost(0.0f), mRawLength(0.0f) { @@ -43,6 +45,7 @@ class DicNodeStateScoring { mTotalPrevWordsLanguageCost = 0.0f; mRawLength = 0.0f; mDoubleLetterLevel = NOT_A_DOUBLE_LETTER; + mDigraphIndex = DigraphUtils::NOT_A_DIGRAPH_INDEX; } AK_FORCE_INLINE void init(const DicNodeStateScoring *const scoring) { @@ -54,6 +57,7 @@ class DicNodeStateScoring { mTotalPrevWordsLanguageCost = scoring->mTotalPrevWordsLanguageCost; mRawLength = scoring->mRawLength; mDoubleLetterLevel = scoring->mDoubleLetterLevel; + mDigraphIndex = scoring->mDigraphIndex; } void addCost(const float spatialCost, const float languageCost, const bool doNormalization, @@ -126,6 +130,24 @@ class DicNodeStateScoring { } } + DigraphUtils::DigraphCodePointIndex getDigraphIndex() const { + return mDigraphIndex; + } + + void advanceDigraphIndex() { + switch(mDigraphIndex) { + case DigraphUtils::NOT_A_DIGRAPH_INDEX: + mDigraphIndex = DigraphUtils::FIRST_DIGRAPH_CODEPOINT; + break; + case DigraphUtils::FIRST_DIGRAPH_CODEPOINT: + mDigraphIndex = DigraphUtils::SECOND_DIGRAPH_CODEPOINT; + break; + case DigraphUtils::SECOND_DIGRAPH_CODEPOINT: + mDigraphIndex = DigraphUtils::NOT_A_DIGRAPH_INDEX; + break; + } + } + float getTotalPrevWordsLanguageCost() const { return mTotalPrevWordsLanguageCost; } @@ -135,6 +157,7 @@ class DicNodeStateScoring { // Use a default copy constructor and an assign operator because shallow copies are ok // for this class DoubleLetterLevel mDoubleLetterLevel; + DigraphUtils::DigraphCodePointIndex mDigraphIndex; int16_t mEditCorrectionCount; int16_t mProximityCorrectionCount; diff --git a/native/jni/src/suggest/core/dictionary/shortcut_utils.h b/native/jni/src/suggest/core/dictionary/shortcut_utils.h index e592136cc..c411408ec 100644 --- a/native/jni/src/suggest/core/dictionary/shortcut_utils.h +++ b/native/jni/src/suggest/core/dictionary/shortcut_utils.h @@ -18,7 +18,7 @@ #define LATINIME_SHORTCUT_UTILS #include "defines.h" -#include "dic_node_utils.h" +#include "suggest/core/dicnode/dic_node_utils.h" #include "terminal_attributes.h" namespace latinime { diff --git a/native/jni/src/suggest/core/policy/traversal.h b/native/jni/src/suggest/core/policy/traversal.h index 1d5082ff8..02c358aec 100644 --- a/native/jni/src/suggest/core/policy/traversal.h +++ b/native/jni/src/suggest/core/policy/traversal.h @@ -20,6 +20,9 @@ #include "defines.h" namespace latinime { + +class DicTraverseSession; + class Traversal { public: virtual int getMaxPointerCount() const = 0; diff --git a/native/jni/src/suggest/core/policy/weighting.cpp b/native/jni/src/suggest/core/policy/weighting.cpp index 4d08fa0fa..e62b70423 100644 --- a/native/jni/src/suggest/core/policy/weighting.cpp +++ b/native/jni/src/suggest/core/policy/weighting.cpp @@ -14,14 +14,15 @@ * limitations under the License. */ +#include "suggest/core/policy/weighting.h" + #include "char_utils.h" #include "defines.h" -#include "dic_node.h" -#include "dic_node_profiler.h" -#include "dic_node_utils.h" -#include "dic_traverse_session.h" #include "hash_map_compat.h" -#include "weighting.h" +#include "suggest/core/dicnode/dic_node.h" +#include "suggest/core/dicnode/dic_node_profiler.h" +#include "suggest/core/dicnode/dic_node_utils.h" +#include "suggest/core/session/dic_traverse_session.h" namespace latinime { diff --git a/native/jni/src/suggest/core/policy/weighting.h b/native/jni/src/suggest/core/policy/weighting.h index 83a0f4b45..b92dbe278 100644 --- a/native/jni/src/suggest/core/policy/weighting.h +++ b/native/jni/src/suggest/core/policy/weighting.h @@ -18,6 +18,7 @@ #define LATINIME_WEIGHTING_H #include "defines.h" +#include "hash_map_compat.h" namespace latinime { diff --git a/native/jni/src/suggest/core/session/dic_traverse_session.cpp b/native/jni/src/suggest/core/session/dic_traverse_session.cpp index 1f781dd43..5b783a2ba 100644 --- a/native/jni/src/suggest/core/session/dic_traverse_session.cpp +++ b/native/jni/src/suggest/core/session/dic_traverse_session.cpp @@ -14,12 +14,13 @@ * limitations under the License. */ +#include "suggest/core/session/dic_traverse_session.h" + #include "defines.h" #include "dictionary.h" -#include "dic_node_utils.h" -#include "dic_traverse_session.h" #include "dic_traverse_wrapper.h" #include "jni.h" +#include "suggest/core/dicnode/dic_node_utils.h" namespace latinime { @@ -83,6 +84,10 @@ const uint8_t *DicTraverseSession::getOffsetDict() const { return mDictionary->getOffsetDict(); } +int DicTraverseSession::getDictFlags() const { + return mDictionary->getDictFlags(); +} + void DicTraverseSession::resetCache(const int nextActiveCacheSize, const int maxWords) { mDicNodesCache.reset(nextActiveCacheSize, maxWords); mBigramCacheMap.clear(); diff --git a/native/jni/src/suggest/core/session/dic_traverse_session.h b/native/jni/src/suggest/core/session/dic_traverse_session.h index af036f82b..525d198cd 100644 --- a/native/jni/src/suggest/core/session/dic_traverse_session.h +++ b/native/jni/src/suggest/core/session/dic_traverse_session.h @@ -21,10 +21,10 @@ #include <vector> #include "defines.h" -#include "dic_nodes_cache.h" #include "hash_map_compat.h" #include "jni.h" #include "proximity_info_state.h" +#include "suggest/core/dicnode/dic_nodes_cache.h" namespace latinime { @@ -53,7 +53,7 @@ class DicTraverseSession { void resetCache(const int nextActiveCacheSize, const int maxWords); const uint8_t *getOffsetDict() const; - bool canUseCache() const; + int getDictFlags() const; //-------------------- // getters and setters diff --git a/native/jni/src/suggest/core/suggest.cpp b/native/jni/src/suggest/core/suggest.cpp index 7fba1d504..63bb20004 100644 --- a/native/jni/src/suggest/core/suggest.cpp +++ b/native/jni/src/suggest/core/suggest.cpp @@ -14,18 +14,21 @@ * limitations under the License. */ +#include "suggest/core/suggest.h" + #include "char_utils.h" #include "dictionary.h" -#include "dic_node_priority_queue.h" -#include "dic_node_vector.h" -#include "dic_traverse_session.h" +#include "digraph_utils.h" #include "proximity_info.h" -#include "scoring.h" -#include "shortcut_utils.h" -#include "suggest.h" +#include "suggest/core/dicnode/dic_node.h" +#include "suggest/core/dicnode/dic_node_priority_queue.h" +#include "suggest/core/dicnode/dic_node_vector.h" +#include "suggest/core/dictionary/shortcut_utils.h" +#include "suggest/core/policy/scoring.h" +#include "suggest/core/policy/traversal.h" +#include "suggest/core/policy/weighting.h" +#include "suggest/core/session/dic_traverse_session.h" #include "terminal_attributes.h" -#include "traversal.h" -#include "weighting.h" namespace latinime { @@ -219,7 +222,7 @@ int Suggest::outputSuggestions(DicTraverseSession *traverseSession, int *frequen void Suggest::expandCurrentDicNodes(DicTraverseSession *traverseSession) const { const int inputSize = traverseSession->getInputSize(); DicNodeVector childDicNodes(TRAVERSAL->getDefaultExpandDicNodeSize()); - DicNode omissionDicNode; + DicNode correctionDicNode; // TODO: Find more efficient caching const bool shouldDepthLevelCache = TRAVERSAL->shouldDepthLevelCache(traverseSession); @@ -255,7 +258,10 @@ void Suggest::expandCurrentDicNodes(DicTraverseSession *traverseSession) const { dicNode.setCached(); } - if (isLookAheadCorrection) { + if (dicNode.isInDigraph()) { + // Finish digraph handling if the node is in the middle of a digraph expansion. + processDicNodeAsDigraph(traverseSession, &dicNode); + } else if (isLookAheadCorrection) { // The algorithm maintains a small set of "deferred" nodes that have not consumed the // latest touch point yet. These are needed to apply look-ahead correction operations // that require special handling of the latest touch point. For example, with insertions @@ -289,12 +295,18 @@ void Suggest::expandCurrentDicNodes(DicTraverseSession *traverseSession) const { processDicNodeAsMatch(traverseSession, childDicNode); continue; } + if (DigraphUtils::hasDigraphForCodePoint(traverseSession->getDictFlags(), + childDicNode->getNodeCodePoint())) { + correctionDicNode.initByCopy(childDicNode); + correctionDicNode.advanceDigraphIndex(); + processDicNodeAsDigraph(traverseSession, &correctionDicNode); + } if (allowsErrorCorrections && TRAVERSAL->isOmission(traverseSession, &dicNode, childDicNode)) { // TODO: (Gesture) Change weight between omission and substitution errors // TODO: (Gesture) Terminal node should not be handled as omission - omissionDicNode.initByCopy(childDicNode); - processDicNodeAsOmission(traverseSession, &omissionDicNode); + correctionDicNode.initByCopy(childDicNode); + processDicNodeAsOmission(traverseSession, &correctionDicNode); } const ProximityType proximityType = TRAVERSAL->getProximityType( traverseSession, &dicNode, childDicNode); @@ -398,6 +410,16 @@ void Suggest::processDicNodeAsSubstitution(DicTraverseSession *traverseSession, processExpandedDicNode(traverseSession, childDicNode); } +// Process the node codepoint as a digraph. This means that composite glyphs like the German +// u-umlaut is expanded to the transliteration "ue". Note that this happens in parallel with +// the normal non-digraph traversal, so both "uber" and "ueber" can be corrected to "[u-umlaut]ber". +void Suggest::processDicNodeAsDigraph(DicTraverseSession *traverseSession, + DicNode *childDicNode) const { + weightChildNode(traverseSession, childDicNode); + childDicNode->advanceDigraphIndex(); + processExpandedDicNode(traverseSession, childDicNode); +} + /** * Handle the dicNode as an omission error (e.g., ths => this). Skip the current letter and consider * matches for all possible next letters. Note that just skipping the current letter without any @@ -424,7 +446,6 @@ void Suggest::processDicNodeAsOmission( weightChildNode(traverseSession, childDicNode); if (!TRAVERSAL->isPossibleOmissionChildNode(traverseSession, dicNode, childDicNode)) { - DicNode::managedDelete(childDicNode); continue; } processExpandedDicNode(traverseSession, childDicNode); diff --git a/native/jni/src/suggest/core/suggest.h b/native/jni/src/suggest/core/suggest.h index 75d646bdd..136c4e548 100644 --- a/native/jni/src/suggest/core/suggest.h +++ b/native/jni/src/suggest/core/suggest.h @@ -18,11 +18,20 @@ #define LATINIME_SUGGEST_IMPL_H #include "defines.h" -#include "suggest_interface.h" -#include "suggest_policy.h" +#include "suggest/core/suggest_interface.h" +#include "suggest/core/policy/suggest_policy.h" namespace latinime { +// Naming convention +// - Distance: "Weighted" edit distance -- used both for spatial and language. +// - Compound Distance: Spatial Distance + Language Distance -- used for pruning and scoring +// - Cost: delta/diff for Distance -- used both for spatial and language +// - Length: "Non-weighted" -- used only for spatial +// - Probability: "Non-weighted" -- used only for language +// - Score: Final calibrated score based on the compound distance, which is sent to java as the +// priority of a suggested word + class DicNode; class DicTraverseSession; class ProximityInfo; @@ -55,6 +64,7 @@ class Suggest : public SuggestInterface { void generateFeatures( DicTraverseSession *traverseSession, DicNode *dicNode, float *features) const; void processDicNodeAsOmission(DicTraverseSession *traverseSession, DicNode *dicNode) const; + void processDicNodeAsDigraph(DicTraverseSession *traverseSession, DicNode *dicNode) const; void processDicNodeAsTransposition(DicTraverseSession *traverseSession, DicNode *dicNode) const; void processDicNodeAsInsertion(DicTraverseSession *traverseSession, DicNode *dicNode) const; diff --git a/native/jni/src/suggest/suggest_interface.h b/native/jni/src/suggest/core/suggest_interface.h index 0bb85d7e5..0bb85d7e5 100644 --- a/native/jni/src/suggest/suggest_interface.h +++ b/native/jni/src/suggest/core/suggest_interface.h diff --git a/native/jni/src/suggest/gesture_suggest.h b/native/jni/src/suggest/gesture_suggest.h deleted file mode 100644 index 82c3a69ad..000000000 --- a/native/jni/src/suggest/gesture_suggest.h +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright (C) 2012 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef LATINIME_GESTURE_SUGGEST_H -#define LATINIME_GESTURE_SUGGEST_H - -#include "defines.h" -#include "suggest_interface.h" - -namespace latinime { - -class ProximityInfo; - -class GestureSuggest : public SuggestInterface { - public: - GestureSuggest() : mSuggestInterface(getGestureSuggestInstance()) {} - - virtual ~GestureSuggest(); - - int getSuggestions(ProximityInfo *pInfo, void *traverseSession, int *inputXs, int *inputYs, - int *times, int *pointerIds, int *inputCodePoints, int inputSize, int commitPoint, - int *outWords, int *frequencies, int *outputIndices, int *outputTypes) const { - if (!mSuggestInterface) { - return 0; - } - return mSuggestInterface->getSuggestions(pInfo, traverseSession, inputXs, inputYs, times, - pointerIds, inputCodePoints, inputSize, commitPoint, outWords, frequencies, - outputIndices, outputTypes); - } - - static void setGestureSuggestFactoryMethod(SuggestInterface *(*factoryMethod)()) { - sGestureSuggestFactoryMethod = factoryMethod; - } - - private: - DISALLOW_COPY_AND_ASSIGN(GestureSuggest); - static SuggestInterface *getGestureSuggestInstance() { - if (!sGestureSuggestFactoryMethod) { - return 0; - } - return sGestureSuggestFactoryMethod(); - } - - static SuggestInterface *(*sGestureSuggestFactoryMethod)(); - SuggestInterface *mSuggestInterface; -}; -} // namespace latinime -#endif // LATINIME_GESTURE_SUGGEST_H diff --git a/native/jni/src/suggest/typing_suggest.cpp b/native/jni/src/suggest/policyimpl/gesture/gesture_suggest_policy_factory.cpp index 56bd5b69a..6d3173937 100644 --- a/native/jni/src/suggest/typing_suggest.cpp +++ b/native/jni/src/suggest/policyimpl/gesture/gesture_suggest_policy_factory.cpp @@ -14,12 +14,8 @@ * limitations under the License. */ -#include "typing_suggest.h" +#include "gesture_suggest_policy_factory.h" namespace latinime { - SuggestInterface *(*TypingSuggest::sTypingSuggestFactoryMethod)() = 0; - - TypingSuggest::~TypingSuggest() { - delete mSuggestInterface; - } + const SuggestPolicy *(*GestureSuggestPolicyFactory::sGestureSuggestFactoryMethod)() = 0; } // namespace latinime diff --git a/native/jni/src/suggest/policyimpl/gesture/gesture_suggest_policy_factory.h b/native/jni/src/suggest/policyimpl/gesture/gesture_suggest_policy_factory.h new file mode 100644 index 000000000..509b01fc0 --- /dev/null +++ b/native/jni/src/suggest/policyimpl/gesture/gesture_suggest_policy_factory.h @@ -0,0 +1,44 @@ +/* + * Copyright (C) 2012 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef LATINIME_GESTURE_SUGGEST_POLICY_FACTORY_H +#define LATINIME_GESTURE_SUGGEST_POLICY_FACTORY_H + +#include "defines.h" + +namespace latinime { + +class SuggestPolicy; + +class GestureSuggestPolicyFactory { + public: + static void setGestureSuggestPolicyFactoryMethod(const SuggestPolicy *(*factoryMethod)()) { + sGestureSuggestFactoryMethod = factoryMethod; + } + + static const SuggestPolicy *getGestureSuggestPolicy() { + if (!sGestureSuggestFactoryMethod) { + return 0; + } + return sGestureSuggestFactoryMethod(); + } + + private: + DISALLOW_COPY_AND_ASSIGN(GestureSuggestPolicyFactory); + static const SuggestPolicy *(*sGestureSuggestFactoryMethod)(); +}; +} // namespace latinime +#endif // LATINIME_GESTURE_SUGGEST_POLICY_FACTORY_H diff --git a/native/jni/src/suggest/policyimpl/typing/scoring_params.cpp b/native/jni/src/suggest/policyimpl/typing/scoring_params.cpp index 90985d0fe..0fa684f01 100644 --- a/native/jni/src/suggest/policyimpl/typing/scoring_params.cpp +++ b/native/jni/src/suggest/policyimpl/typing/scoring_params.cpp @@ -14,7 +14,7 @@ * limitations under the License. */ -#include "scoring_params.h" +#include "suggest/policyimpl/typing/scoring_params.h" namespace latinime { // TODO: RENAME all diff --git a/native/jni/src/suggest/policyimpl/typing/typing_scoring.cpp b/native/jni/src/suggest/policyimpl/typing/typing_scoring.cpp index 53f68f20f..d8c6175e2 100644 --- a/native/jni/src/suggest/policyimpl/typing/typing_scoring.cpp +++ b/native/jni/src/suggest/policyimpl/typing/typing_scoring.cpp @@ -14,7 +14,7 @@ * limitations under the License. */ -#include "typing_scoring.h" +#include "suggest/policyimpl/typing/typing_scoring.h" namespace latinime { const TypingScoring TypingScoring::sInstance; diff --git a/native/jni/src/suggest/policyimpl/typing/typing_scoring.h b/native/jni/src/suggest/policyimpl/typing/typing_scoring.h index ed941f0ae..90e2133e7 100644 --- a/native/jni/src/suggest/policyimpl/typing/typing_scoring.h +++ b/native/jni/src/suggest/policyimpl/typing/typing_scoring.h @@ -18,8 +18,8 @@ #define LATINIME_TYPING_SCORING_H #include "defines.h" -#include "scoring.h" -#include "scoring_params.h" +#include "suggest/core/policy/scoring.h" +#include "suggest/policyimpl/typing/scoring_params.h" namespace latinime { diff --git a/native/jni/src/suggest/policyimpl/typing/typing_suggest_policy.cpp b/native/jni/src/suggest/policyimpl/typing/typing_suggest_policy.cpp index ebba37531..0c2763967 100644 --- a/native/jni/src/suggest/policyimpl/typing/typing_suggest_policy.cpp +++ b/native/jni/src/suggest/policyimpl/typing/typing_suggest_policy.cpp @@ -14,29 +14,8 @@ * limitations under the License. */ -#include "suggest.h" -#include "typing_suggest.h" -#include "typing_suggest_policy.h" +#include "suggest/policyimpl/typing/typing_suggest_policy.h" namespace latinime { - const TypingSuggestPolicy TypingSuggestPolicy::sInstance; - -// A factory method for a "typing" Suggest instance -static SuggestInterface *getTypingSuggestInstance() { - return new Suggest(TypingSuggestPolicy::getInstance()); -} - -// An ad-hoc internal class to register the factory method getTypingSuggestInstance() defined above -class TypingSuggestFactoryRegisterer { - public: - TypingSuggestFactoryRegisterer() { - TypingSuggest::setTypingSuggestFactoryMethod(getTypingSuggestInstance); - } - private: - DISALLOW_COPY_AND_ASSIGN(TypingSuggestFactoryRegisterer); -}; - -// To invoke the TypingSuggestFactoryRegisterer's constructor in the global constructor -static TypingSuggestFactoryRegisterer typingSuggestFactoryregisterer; } // namespace latinime diff --git a/native/jni/src/suggest/policyimpl/typing/typing_suggest_policy.h b/native/jni/src/suggest/policyimpl/typing/typing_suggest_policy.h index 55668fc25..35f48097c 100644 --- a/native/jni/src/suggest/policyimpl/typing/typing_suggest_policy.h +++ b/native/jni/src/suggest/policyimpl/typing/typing_suggest_policy.h @@ -18,10 +18,10 @@ #define LATINIME_TYPING_SUGGEST_POLICY_H #include "defines.h" -#include "suggest_policy.h" -#include "typing_scoring.h" -#include "typing_traversal.h" -#include "typing_weighting.h" +#include "suggest/core/policy/suggest_policy.h" +#include "suggest/policyimpl/typing/typing_scoring.h" +#include "suggest/policyimpl/typing/typing_traversal.h" +#include "suggest/policyimpl/typing/typing_weighting.h" namespace latinime { diff --git a/native/jni/src/suggest/gesture_suggest.cpp b/native/jni/src/suggest/policyimpl/typing/typing_suggest_policy_factory.h index fce5621d5..a67b45b1b 100644 --- a/native/jni/src/suggest/gesture_suggest.cpp +++ b/native/jni/src/suggest/policyimpl/typing/typing_suggest_policy_factory.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2012 The Android Open Source Project + * Copyright (C) 2013 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -14,12 +14,24 @@ * limitations under the License. */ -#include "gesture_suggest.h" +#ifndef LATINIME_TYPING_SUGGEST_POLICY_FACTORY_H +#define LATINIME_TYPING_SUGGEST_POLICY_FACTORY_H + +#include "defines.h" +#include "typing_suggest_policy.h" namespace latinime { - SuggestInterface *(*GestureSuggest::sGestureSuggestFactoryMethod)() = 0; - GestureSuggest::~GestureSuggest() { - delete mSuggestInterface; +class SuggestPolicy; + +class TypingSuggestPolicyFactory { + public: + static const SuggestPolicy *getTypingSuggestPolicy() { + return TypingSuggestPolicy::getInstance(); } + + private: + DISALLOW_COPY_AND_ASSIGN(TypingSuggestPolicyFactory); +}; } // namespace latinime +#endif // LATINIME_TYPING_SUGGEST_POLICY_FACTORY_H diff --git a/native/jni/src/suggest/policyimpl/typing/typing_traversal.cpp b/native/jni/src/suggest/policyimpl/typing/typing_traversal.cpp index 68c614e77..66f8ba9fa 100644 --- a/native/jni/src/suggest/policyimpl/typing/typing_traversal.cpp +++ b/native/jni/src/suggest/policyimpl/typing/typing_traversal.cpp @@ -14,7 +14,7 @@ * limitations under the License. */ -#include "typing_traversal.h" +#include "suggest/policyimpl/typing/typing_traversal.h" namespace latinime { const bool TypingTraversal::CORRECT_OMISSION = true; diff --git a/native/jni/src/suggest/policyimpl/typing/typing_traversal.h b/native/jni/src/suggest/policyimpl/typing/typing_traversal.h index 16153f8bb..f22029a2c 100644 --- a/native/jni/src/suggest/policyimpl/typing/typing_traversal.h +++ b/native/jni/src/suggest/policyimpl/typing/typing_traversal.h @@ -21,12 +21,12 @@ #include "char_utils.h" #include "defines.h" -#include "dic_node.h" -#include "dic_node_vector.h" -#include "dic_traverse_session.h" #include "proximity_info_state.h" -#include "scoring_params.h" -#include "traversal.h" +#include "suggest/core/dicnode/dic_node.h" +#include "suggest/core/dicnode/dic_node_vector.h" +#include "suggest/core/policy/traversal.h" +#include "suggest/core/session/dic_traverse_session.h" +#include "suggest/policyimpl/typing/scoring_params.h" namespace latinime { class TypingTraversal : public Traversal { diff --git a/native/jni/src/suggest/policyimpl/typing/typing_weighting.cpp b/native/jni/src/suggest/policyimpl/typing/typing_weighting.cpp index 6e4b2fb6a..1500341bd 100644 --- a/native/jni/src/suggest/policyimpl/typing/typing_weighting.cpp +++ b/native/jni/src/suggest/policyimpl/typing/typing_weighting.cpp @@ -14,9 +14,10 @@ * limitations under the License. */ -#include "dic_node.h" -#include "scoring_params.h" -#include "typing_weighting.h" +#include "suggest/policyimpl/typing/typing_weighting.h" + +#include "suggest/core/dicnode/dic_node.h" +#include "suggest/policyimpl/typing/scoring_params.h" namespace latinime { const TypingWeighting TypingWeighting::sInstance; diff --git a/native/jni/src/suggest/policyimpl/typing/typing_weighting.h b/native/jni/src/suggest/policyimpl/typing/typing_weighting.h index e8075f41a..52d54eb0f 100644 --- a/native/jni/src/suggest/policyimpl/typing/typing_weighting.h +++ b/native/jni/src/suggest/policyimpl/typing/typing_weighting.h @@ -18,9 +18,10 @@ #define LATINIME_TYPING_WEIGHTING_H #include "defines.h" -#include "dic_node_utils.h" -#include "dic_traverse_session.h" -#include "weighting.h" +#include "suggest/core/dicnode/dic_node_utils.h" +#include "suggest/core/policy/weighting.h" +#include "suggest/core/session/dic_traverse_session.h" +#include "suggest/policyimpl/typing/scoring_params.h" namespace latinime { diff --git a/native/jni/src/suggest/typing_suggest.h b/native/jni/src/suggest/typing_suggest.h deleted file mode 100644 index 678037aa2..000000000 --- a/native/jni/src/suggest/typing_suggest.h +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright (C) 2012 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef LATINIME_TYPING_SUGGEST_H -#define LATINIME_TYPING_SUGGEST_H - -#include "defines.h" -#include "suggest_interface.h" - -namespace latinime { - -class ProximityInfo; - -class TypingSuggest : public SuggestInterface { - public: - TypingSuggest() : mSuggestInterface(getTypingSuggestInstance()) {} - - virtual ~TypingSuggest(); - - int getSuggestions(ProximityInfo *pInfo, void *traverseSession, int *inputXs, int *inputYs, - int *times, int *pointerIds, int *inputCodePoints, int inputSize, int commitPoint, - int *outWords, int *frequencies, int *outputIndices, int *outputTypes) const { - if (!mSuggestInterface) { - return 0; - } - return mSuggestInterface->getSuggestions(pInfo, traverseSession, inputXs, inputYs, times, - pointerIds, inputCodePoints, inputSize, commitPoint, outWords, frequencies, - outputIndices, outputTypes); - } - - static void setTypingSuggestFactoryMethod(SuggestInterface *(*factoryMethod)()) { - sTypingSuggestFactoryMethod = factoryMethod; - } - - private: - DISALLOW_COPY_AND_ASSIGN(TypingSuggest); - static SuggestInterface *getTypingSuggestInstance() { - if (!sTypingSuggestFactoryMethod) { - return 0; - } - return sTypingSuggestFactoryMethod(); - } - - static SuggestInterface *(*sTypingSuggestFactoryMethod)(); - SuggestInterface *mSuggestInterface; -}; -} // namespace latinime -#endif // LATINIME_TYPING_SUGGEST_H diff --git a/native/jni/src/unigram_dictionary.cpp b/native/jni/src/unigram_dictionary.cpp index 80ba412a3..a672294b5 100644 --- a/native/jni/src/unigram_dictionary.cpp +++ b/native/jni/src/unigram_dictionary.cpp @@ -22,6 +22,7 @@ #include "char_utils.h" #include "defines.h" #include "dictionary.h" +#include "digraph_utils.h" #include "proximity_info.h" #include "terminal_attributes.h" #include "unigram_dictionary.h" @@ -30,19 +31,10 @@ namespace latinime { -const UnigramDictionary::digraph_t UnigramDictionary::GERMAN_UMLAUT_DIGRAPHS[] = - { { 'a', 'e', 0x00E4 }, // U+00E4 : LATIN SMALL LETTER A WITH DIAERESIS - { 'o', 'e', 0x00F6 }, // U+00F6 : LATIN SMALL LETTER O WITH DIAERESIS - { 'u', 'e', 0x00FC } }; // U+00FC : LATIN SMALL LETTER U WITH DIAERESIS - -const UnigramDictionary::digraph_t UnigramDictionary::FRENCH_LIGATURES_DIGRAPHS[] = - { { 'a', 'e', 0x00E6 }, // U+00E6 : LATIN SMALL LETTER AE - { 'o', 'e', 0x0153 } }; // U+0153 : LATIN SMALL LIGATURE OE - // TODO: check the header -UnigramDictionary::UnigramDictionary(const uint8_t *const streamStart, const unsigned int flags) +UnigramDictionary::UnigramDictionary(const uint8_t *const streamStart, const unsigned int dictFlags) : DICT_ROOT(streamStart), ROOT_POS(0), - MAX_DIGRAPH_SEARCH_DEPTH(DEFAULT_MAX_DIGRAPH_SEARCH_DEPTH), FLAGS(flags) { + MAX_DIGRAPH_SEARCH_DEPTH(DEFAULT_MAX_DIGRAPH_SEARCH_DEPTH), DICT_FLAGS(dictFlags) { if (DEBUG_DICT) { AKLOGI("UnigramDictionary - constructor"); } @@ -58,7 +50,7 @@ static void addWord(int *word, int length, int probability, WordsPriorityQueue * // Return the replacement code point for a digraph, or 0 if none. int UnigramDictionary::getDigraphReplacement(const int *codes, const int i, const int inputSize, - const digraph_t *const digraphs, const unsigned int digraphsSize) const { + const DigraphUtils::digraph_t *const digraphs, const unsigned int digraphsSize) const { // There can't be a digraph if we don't have at least 2 characters to examine if (i + 2 > inputSize) return false; @@ -74,7 +66,7 @@ int UnigramDictionary::getDigraphReplacement(const int *codes, const int i, cons // It's an interesting digraph if the second char matches too. if (digraphs[lastDigraphIndex].second == codes[i + 1]) { - return digraphs[lastDigraphIndex].replacement; + return digraphs[lastDigraphIndex].compositeGlyph; } else { return 0; } @@ -93,7 +85,7 @@ void UnigramDictionary::getWordWithDigraphSuggestionsRec(ProximityInfo *proximit const bool useFullEditDistance, const int *codesSrc, const int codesRemain, const int currentDepth, int *codesDest, Correction *correction, WordsPriorityQueuePool *queuePool, - const digraph_t *const digraphs, const unsigned int digraphsSize) const { + const DigraphUtils::digraph_t *const digraphs, const unsigned int digraphsSize) const { ASSERT(sizeof(codesDest[0]) == sizeof(codesSrc[0])); ASSERT(sizeof(xCoordinatesBuffer[0]) == sizeof(xcoordinates[0])); ASSERT(sizeof(yCoordinatesBuffer[0]) == sizeof(ycoordinates[0])); @@ -169,7 +161,10 @@ int UnigramDictionary::getSuggestions(ProximityInfo *proximityInfo, const int *x queuePool.clearAll(); Correction masterCorrection; masterCorrection.resetCorrection(); - if (BinaryFormat::REQUIRES_GERMAN_UMLAUT_PROCESSING & FLAGS) + const DigraphUtils::digraph_t *digraphs = 0; + const int digraphsSize = + DigraphUtils::getAllDigraphsForDictionaryAndReturnSize(DICT_FLAGS, &digraphs); + if (digraphsSize > 0) { // Incrementally tune the word and try all possibilities int codesBuffer[sizeof(*inputCodePoints) * inputSize]; int xCoordinatesBuffer[inputSize]; @@ -177,15 +172,7 @@ int UnigramDictionary::getSuggestions(ProximityInfo *proximityInfo, const int *x getWordWithDigraphSuggestionsRec(proximityInfo, xcoordinates, ycoordinates, codesBuffer, xCoordinatesBuffer, yCoordinatesBuffer, inputSize, bigramMap, bigramFilter, useFullEditDistance, inputCodePoints, inputSize, 0, codesBuffer, &masterCorrection, - &queuePool, GERMAN_UMLAUT_DIGRAPHS, NELEMS(GERMAN_UMLAUT_DIGRAPHS)); - } else if (BinaryFormat::REQUIRES_FRENCH_LIGATURES_PROCESSING & FLAGS) { - int codesBuffer[sizeof(*inputCodePoints) * inputSize]; - int xCoordinatesBuffer[inputSize]; - int yCoordinatesBuffer[inputSize]; - getWordWithDigraphSuggestionsRec(proximityInfo, xcoordinates, ycoordinates, codesBuffer, - xCoordinatesBuffer, yCoordinatesBuffer, inputSize, bigramMap, bigramFilter, - useFullEditDistance, inputCodePoints, inputSize, 0, codesBuffer, &masterCorrection, - &queuePool, FRENCH_LIGATURES_DIGRAPHS, NELEMS(FRENCH_LIGATURES_DIGRAPHS)); + &queuePool, digraphs, digraphsSize); } else { // Normal processing getWordSuggestions(proximityInfo, xcoordinates, ycoordinates, inputCodePoints, inputSize, bigramMap, bigramFilter, useFullEditDistance, &masterCorrection, &queuePool); diff --git a/native/jni/src/unigram_dictionary.h b/native/jni/src/unigram_dictionary.h index c1955e8bb..a64a539bd 100644 --- a/native/jni/src/unigram_dictionary.h +++ b/native/jni/src/unigram_dictionary.h @@ -20,6 +20,7 @@ #include <map> #include <stdint.h> #include "defines.h" +#include "digraph_utils.h" namespace latinime { @@ -29,8 +30,6 @@ class TerminalAttributes; class WordsPriorityQueuePool; class UnigramDictionary { - typedef struct { int first; int second; int replacement; } digraph_t; - public: // Error tolerances static const int DEFAULT_MAX_ERRORS = 2; @@ -39,7 +38,7 @@ class UnigramDictionary { static const int FLAG_MULTIPLE_SUGGEST_ABORT = 0; static const int FLAG_MULTIPLE_SUGGEST_SKIP = 1; static const int FLAG_MULTIPLE_SUGGEST_CONTINUE = 2; - UnigramDictionary(const uint8_t *const streamStart, const unsigned int flags); + UnigramDictionary(const uint8_t *const streamStart, const unsigned int dictFlags); int getProbability(const int *const inWord, const int length) const; int getBigramPosition(int pos, int *word, int offset, int length) const; int getSuggestions(ProximityInfo *proximityInfo, const int *xcoordinates, @@ -47,6 +46,7 @@ class UnigramDictionary { const std::map<int, int> *bigramMap, const uint8_t *bigramFilter, const bool useFullEditDistance, int *outWords, int *frequencies, int *outputTypes) const; + int getDictFlags() const { return DICT_FLAGS; } virtual ~UnigramDictionary(); private: @@ -57,13 +57,13 @@ class UnigramDictionary { const bool useFullEditDistance, Correction *correction, WordsPriorityQueuePool *queuePool) const; int getDigraphReplacement(const int *codes, const int i, const int inputSize, - const digraph_t *const digraphs, const unsigned int digraphsSize) const; + const DigraphUtils::digraph_t *const digraphs, const unsigned int digraphsSize) const; void getWordWithDigraphSuggestionsRec(ProximityInfo *proximityInfo, const int *xcoordinates, const int *ycoordinates, const int *codesBuffer, int *xCoordinatesBuffer, int *yCoordinatesBuffer, const int codesBufferSize, const std::map<int, int> *bigramMap, const uint8_t *bigramFilter, const bool useFullEditDistance, const int *codesSrc, const int codesRemain, const int currentDepth, int *codesDest, Correction *correction, - WordsPriorityQueuePool *queuePool, const digraph_t *const digraphs, + WordsPriorityQueuePool *queuePool, const DigraphUtils::digraph_t *const digraphs, const unsigned int digraphsSize) const; void initSuggestions(ProximityInfo *proximityInfo, const int *xcoordinates, const int *ycoordinates, const int *codes, const int inputSize, @@ -110,10 +110,7 @@ class UnigramDictionary { const uint8_t *const DICT_ROOT; const int ROOT_POS; const int MAX_DIGRAPH_SEARCH_DEPTH; - const int FLAGS; - - static const digraph_t GERMAN_UMLAUT_DIGRAPHS[]; - static const digraph_t FRENCH_LIGATURES_DIGRAPHS[]; + const int DICT_FLAGS; }; } // namespace latinime #endif // LATINIME_UNIGRAM_DICTIONARY_H |