diff options
Diffstat (limited to 'native/jni/src')
-rw-r--r-- | native/jni/src/correction.cpp | 2 | ||||
-rw-r--r-- | native/jni/src/dic_traverse_wrapper.cpp | 26 | ||||
-rw-r--r-- | native/jni/src/dic_traverse_wrapper.h | 66 | ||||
-rw-r--r-- | native/jni/src/dictionary.cpp | 16 | ||||
-rw-r--r-- | native/jni/src/dictionary.h | 4 | ||||
-rw-r--r-- | native/jni/src/geometry_utils.h | 101 | ||||
-rw-r--r-- | native/jni/src/gesture/gesture_decoder_wrapper.h | 14 | ||||
-rw-r--r-- | native/jni/src/gesture/incremental_decoder_interface.h | 4 | ||||
-rw-r--r-- | native/jni/src/gesture/incremental_decoder_wrapper.h | 14 | ||||
-rw-r--r-- | native/jni/src/proximity_info.cpp | 68 | ||||
-rw-r--r-- | native/jni/src/proximity_info.h | 18 | ||||
-rw-r--r-- | native/jni/src/unigram_dictionary.cpp | 18 | ||||
-rw-r--r-- | native/jni/src/words_priority_queue.h | 17 |
13 files changed, 311 insertions, 57 deletions
diff --git a/native/jni/src/correction.cpp b/native/jni/src/correction.cpp index ea4bddae2..b18b35e8c 100644 --- a/native/jni/src/correction.cpp +++ b/native/jni/src/correction.cpp @@ -154,8 +154,6 @@ void Correction::checkState() { if (mSkipPos >= 0) ++inputCount; if (mExcessivePos >= 0) ++inputCount; if (mTransposedPos >= 0) ++inputCount; - // TODO: remove this assert - assert(inputCount <= 1); } } diff --git a/native/jni/src/dic_traverse_wrapper.cpp b/native/jni/src/dic_traverse_wrapper.cpp new file mode 100644 index 000000000..1f7dcbfb2 --- /dev/null +++ b/native/jni/src/dic_traverse_wrapper.cpp @@ -0,0 +1,26 @@ +/* + * 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. + */ + +#define LOG_TAG "LatinIME: jni: Session" + +#include "dic_traverse_wrapper.h" + +namespace latinime { +void *(*DicTraverseWrapper::sDicTraverseSessionFactoryMethod)(JNIEnv *env, jstring locale) = 0; +void (*DicTraverseWrapper::sDicTraverseSessionReleaseMethod)(void *) = 0; +void (*DicTraverseWrapper::sDicTraverseSessionInitMethod)( + void *, Dictionary *, const int *, const int) = 0; +} // namespace latinime diff --git a/native/jni/src/dic_traverse_wrapper.h b/native/jni/src/dic_traverse_wrapper.h new file mode 100644 index 000000000..8396d0027 --- /dev/null +++ b/native/jni/src/dic_traverse_wrapper.h @@ -0,0 +1,66 @@ +/* + * 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_DIC_TRAVERSE_WRAPPER_H +#define LATINIME_DIC_TRAVERSE_WRAPPER_H + +#include <stdint.h> + +#include "defines.h" +#include "jni.h" + +namespace latinime { +class Dictionary; +// TODO: Remove +class DicTraverseWrapper { + public: + static void *getDicTraverseSession(JNIEnv *env, jstring locale) { + if (sDicTraverseSessionFactoryMethod) { + return sDicTraverseSessionFactoryMethod(env, locale); + } + return 0; + } + static void initDicTraverseSession(void *traverseSession, + Dictionary *dictionary, const int *prevWord, const int prevWordLength) { + if (sDicTraverseSessionInitMethod) { + sDicTraverseSessionInitMethod(traverseSession, dictionary, prevWord, prevWordLength); + } + } + static void releaseDicTraverseSession(void *traverseSession) { + if (sDicTraverseSessionReleaseMethod) { + sDicTraverseSessionReleaseMethod(traverseSession); + } + } + static void setTraverseSessionFactoryMethod( + void *(*factoryMethod)(JNIEnv *env, jstring locale)) { + sDicTraverseSessionFactoryMethod = factoryMethod; + } + static void setTraverseSessionInitMethod( + void (*initMethod)(void *, Dictionary *, const int *, const int)) { + sDicTraverseSessionInitMethod = initMethod; + } + static void setTraverseSessionReleaseMethod(void (*releaseMethod)(void *)) { + sDicTraverseSessionReleaseMethod = releaseMethod; + } + private: + DISALLOW_IMPLICIT_CONSTRUCTORS(DicTraverseWrapper); + static void *(*sDicTraverseSessionFactoryMethod)(JNIEnv *, jstring); + static void (*sDicTraverseSessionInitMethod)(void *, Dictionary *, const int *, const int); + static void (*sDicTraverseSessionReleaseMethod)(void *); +}; +int register_DicTraverseSession(JNIEnv *env); +} // namespace latinime +#endif // LATINIME_DIC_TRAVERSE_WRAPPER_H diff --git a/native/jni/src/dictionary.cpp b/native/jni/src/dictionary.cpp index 8c785a263..f3bdb310d 100644 --- a/native/jni/src/dictionary.cpp +++ b/native/jni/src/dictionary.cpp @@ -22,6 +22,7 @@ #include "binary_format.h" #include "defines.h" #include "dictionary.h" +#include "dic_traverse_wrapper.h" #include "gesture_decoder_wrapper.h" #include "unigram_dictionary.h" @@ -31,8 +32,9 @@ namespace latinime { Dictionary::Dictionary(void *dict, int dictSize, int mmapFd, int dictBufAdjust, int typedLetterMultiplier, int fullWordMultiplier, int maxWordLength, int maxWords, int maxPredictions) - : mDict((unsigned char*) dict), mDictSize(dictSize), - mMmapFd(mmapFd), mDictBufAdjust(dictBufAdjust) { + : mDict((unsigned char*) dict), + mOffsetDict(((unsigned char*) dict) + BinaryFormat::getHeaderSize(mDict)), + mDictSize(dictSize), mMmapFd(mmapFd), mDictBufAdjust(dictBufAdjust) { if (DEBUG_DICT) { if (MAX_WORD_LENGTH_INTERNAL < maxWordLength) { AKLOGI("Max word length (%d) is greater than %d", @@ -40,14 +42,13 @@ Dictionary::Dictionary(void *dict, int dictSize, int mmapFd, int dictBufAdjust, AKLOGI("IN NATIVE SUGGEST Version: %d", (mDict[0] & 0xFF)); } } - const unsigned int headerSize = BinaryFormat::getHeaderSize(mDict); const unsigned int options = BinaryFormat::getFlags(mDict); - mUnigramDictionary = new UnigramDictionary(mDict + headerSize, typedLetterMultiplier, + mUnigramDictionary = new UnigramDictionary(mOffsetDict, typedLetterMultiplier, fullWordMultiplier, maxWordLength, maxWords, options); - mBigramDictionary = new BigramDictionary(mDict + headerSize, maxWordLength, maxPredictions); + mBigramDictionary = new BigramDictionary(mOffsetDict, maxWordLength, maxPredictions); mGestureDecoder = new GestureDecoderWrapper(maxWordLength, maxWords); mGestureDecoder->setDict(mUnigramDictionary, mBigramDictionary, - mDict + headerSize /* dict root */, 0 /* root pos */); + mOffsetDict /* dict root */, 0 /* root pos */); } Dictionary::~Dictionary() { @@ -64,7 +65,8 @@ int Dictionary::getSuggestions(ProximityInfo *proximityInfo, void *traverseSessi int *frequencies, int *spaceIndices, int *outputTypes) { int result = 0; if (isGesture) { - mGestureDecoder->setPrevWord(prevWordChars, prevWordLength); + DicTraverseWrapper::initDicTraverseSession( + traverseSession, this, prevWordChars, prevWordLength); result = mGestureDecoder->getSuggestions(proximityInfo, traverseSession, xcoordinates, ycoordinates, times, pointerIds, codes, codesSize, commitPoint, outWords, frequencies, spaceIndices, outputTypes); diff --git a/native/jni/src/dictionary.h b/native/jni/src/dictionary.h index 2c79527be..b550ba4df 100644 --- a/native/jni/src/dictionary.h +++ b/native/jni/src/dictionary.h @@ -55,7 +55,8 @@ class Dictionary { int getFrequency(const int32_t *word, int length) const; bool isValidBigram(const int32_t *word1, int length1, const int32_t *word2, int length2) const; - void *getDict() const { return (void *)mDict; } + void *getDict() const { return (void *)mDict; } // required to release dictionary buffer + void *getOffsetDict() const { return (void *)mOffsetDict; } int getDictSize() const { return mDictSize; } int getMmapFd() const { return mMmapFd; } int getDictBufAdjust() const { return mDictBufAdjust; } @@ -68,6 +69,7 @@ class Dictionary { private: DISALLOW_IMPLICIT_CONSTRUCTORS(Dictionary); const unsigned char *mDict; + const unsigned char *mOffsetDict; // Used only for the mmap version of dictionary loading, but we use these as dummy variables // also for the malloc version. diff --git a/native/jni/src/geometry_utils.h b/native/jni/src/geometry_utils.h new file mode 100644 index 000000000..ada889e11 --- /dev/null +++ b/native/jni/src/geometry_utils.h @@ -0,0 +1,101 @@ +/* + * 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_INCREMENTAL_GEOMETRY_UTILS_H +#define LATINIME_INCREMENTAL_GEOMETRY_UTILS_H + +#include <cmath> + +#define MAX_DISTANCE 10000000 +#define KEY_NUM 27 +#define SPACE_KEY 26 +#define MAX_PATHS 2 + +#define DEBUG_DECODER false + +namespace latinime { + +static inline float sqr(float x) { + return x * x; +} + +static inline float getNormalizedSqrDistance(int x1, int y1, int x2, int y2, int scale) { + return sqr((x1 - x2) * 1.0 / scale) + sqr((y1 - y2) * 1.0 / scale); +} + +static inline int getDistance(int x1, int y1, int x2, int y2) { + return (int) sqrt(sqr(x2 - x1) + sqr(y2 - y1)); +} + +static inline float getDistanceSq(float x1, float y1, float x2, float y2) { + return sqr(x2 - x1) + sqr(y2 - y1); +} + +static inline float getAngle(int x1, int y1, int x2, int y2) { + float dx = x1 - x2; + float dy = y1 - y2; + if (dx == 0 && dy == 0) + return 0; + return atan2(dy, dx); +} + +static inline float angleDiff(float a1, float a2) { + float diff = a1 - a2; + if (diff < 0) { + diff = -diff; + } + if (diff > M_PI) { + return 2 * M_PI - diff; + } + return diff; +} + +//static float pointToLineDistanceSq(float x, float y, float x1, float y1, float x2, float y2) { +// float A = x - x1; +// float B = y - y1; +// float C = x2 - x1; +// float D = y2 - y1; +// return abs(A * D - C * B) / sqrt(C * C + D * D); +//} + +static inline float pointToLineSegDistanceSq( + float x, float y, float x1, float y1, float x2, float y2) { + float ray1x = x - x1; + float ray1y = y - y1; + float ray2x = x2 - x1; + float ray2y = y2 - y1; + + float dotProduct = ray1x * ray2x + ray1y * ray2y; + float lineLengthSq = ray2x * ray2x + ray2y * ray2y; + float projectionLengthSq = dotProduct / lineLengthSq; + + float projectionX, projectionY; + if (projectionLengthSq < 0) { + projectionX = x1; + projectionY = y1; + } else if (projectionLengthSq > 1) { + projectionX = x2; + projectionY = y2; + } else { + projectionX = x1 + projectionLengthSq * ray2x; + projectionY = y1 + projectionLengthSq * ray2y; + } + + float dist = getDistanceSq(x, y, projectionX, projectionY); + return dist; +} +} // namespace latinime +#endif // LATINIME_INCREMENTAL_GEOMETRY_UTILS_H diff --git a/native/jni/src/gesture/gesture_decoder_wrapper.h b/native/jni/src/gesture/gesture_decoder_wrapper.h index b70c8e0a3..2b9054f70 100644 --- a/native/jni/src/gesture/gesture_decoder_wrapper.h +++ b/native/jni/src/gesture/gesture_decoder_wrapper.h @@ -48,13 +48,6 @@ class GestureDecoderWrapper : public IncrementalDecoderInterface { inputSize, commitPoint, outWords, frequencies, outputIndices, outputTypes); } - void reset() { - if (!mIncrementalDecoderInterface) { - return; - } - mIncrementalDecoderInterface->reset(); - } - void setDict(const UnigramDictionary *dict, const BigramDictionary *bigram, const uint8_t *dictRoot, int rootPos) { if (!mIncrementalDecoderInterface) { @@ -63,13 +56,6 @@ class GestureDecoderWrapper : public IncrementalDecoderInterface { mIncrementalDecoderInterface->setDict(dict, bigram, dictRoot, rootPos); } - void setPrevWord(const int32_t *prevWord, int prevWordLength) { - if (!mIncrementalDecoderInterface) { - return; - } - mIncrementalDecoderInterface->setPrevWord(prevWord, prevWordLength); - } - static void setGestureDecoderFactoryMethod( IncrementalDecoderInterface *(*factoryMethod)(int, int)) { sGestureDecoderFactoryMethod = factoryMethod; diff --git a/native/jni/src/gesture/incremental_decoder_interface.h b/native/jni/src/gesture/incremental_decoder_interface.h index e8d3a5333..3951514c0 100644 --- a/native/jni/src/gesture/incremental_decoder_interface.h +++ b/native/jni/src/gesture/incremental_decoder_interface.h @@ -32,11 +32,11 @@ class IncrementalDecoderInterface { int *inputXs, int *inputYs, int *times, int *pointerIds, int *codes, int inputSize, int commitPoint, unsigned short *outWords, int *frequencies, int *outputIndices, int *outputTypes) = 0; - virtual void reset() = 0; virtual void setDict(const UnigramDictionary *dict, const BigramDictionary *bigram, const uint8_t *dictRoot, int rootPos) = 0; - virtual void setPrevWord(const int32_t *prevWord, int prevWordLength) = 0; virtual ~IncrementalDecoderInterface() { }; + private: + //DISALLOW_COPY_AND_ASSIGN(IncrementalDecoderInterface); }; } // namespace latinime #endif // LATINIME_INCREMENTAL_DECODER_INTERFACE_H diff --git a/native/jni/src/gesture/incremental_decoder_wrapper.h b/native/jni/src/gesture/incremental_decoder_wrapper.h index 8d66b4ec1..477b2cc8a 100644 --- a/native/jni/src/gesture/incremental_decoder_wrapper.h +++ b/native/jni/src/gesture/incremental_decoder_wrapper.h @@ -48,13 +48,6 @@ class IncrementalDecoderWrapper : public IncrementalDecoderInterface { inputSize, commitPoint, outWords, frequencies, outputIndices, outputTypes); } - void reset() { - if (!mIncrementalDecoderInterface) { - return; - } - mIncrementalDecoderInterface->reset(); - } - void setDict(const UnigramDictionary *dict, const BigramDictionary *bigram, const uint8_t *dictRoot, int rootPos) { if (!mIncrementalDecoderInterface) { @@ -63,13 +56,6 @@ class IncrementalDecoderWrapper : public IncrementalDecoderInterface { mIncrementalDecoderInterface->setDict(dict, bigram, dictRoot, rootPos); } - void setPrevWord(const int32_t *prevWord, int prevWordLength) { - if (!mIncrementalDecoderInterface) { - return; - } - mIncrementalDecoderInterface->setPrevWord(prevWord, prevWordLength); - } - static void setIncrementalDecoderFactoryMethod( IncrementalDecoderInterface *(*factoryMethod)(int, int)) { sIncrementalDecoderFactoryMethod = factoryMethod; diff --git a/native/jni/src/proximity_info.cpp b/native/jni/src/proximity_info.cpp index 2564c8a67..18a0b74a8 100644 --- a/native/jni/src/proximity_info.cpp +++ b/native/jni/src/proximity_info.cpp @@ -23,6 +23,7 @@ #include "additional_proximity_chars.h" #include "char_utils.h" #include "defines.h" +#include "geometry_utils.h" #include "jni.h" #include "proximity_info.h" @@ -33,7 +34,7 @@ static inline void safeGetOrFillZeroIntArrayRegion(JNIEnv *env, jintArray jArray if (jArray && buffer) { env->GetIntArrayRegion(jArray, 0, len, buffer); } else if (buffer) { - memset(buffer, 0, len); + memset(buffer, 0, len * sizeof(jint)); } } @@ -42,7 +43,7 @@ static inline void safeGetOrFillZeroFloatArrayRegion(JNIEnv *env, jfloatArray jA if (jArray && buffer) { env->GetFloatArrayRegion(jArray, 0, len, buffer); } else if (buffer) { - memset(buffer, 0, len); + memset(buffer, 0, len * sizeof(jfloat)); } } @@ -55,6 +56,7 @@ ProximityInfo::ProximityInfo(JNIEnv *env, const jstring localeJStr, const int ma const jfloatArray sweetSpotRadii) : MAX_PROXIMITY_CHARS_SIZE(maxProximityCharsSize), KEYBOARD_WIDTH(keyboardWidth), KEYBOARD_HEIGHT(keyboardHeight), GRID_WIDTH(gridWidth), GRID_HEIGHT(gridHeight), + MOST_COMMON_KEY_WIDTH(mostCommonKeyWidth), MOST_COMMON_KEY_WIDTH_SQUARE(mostCommonKeyWidth * mostCommonKeyWidth), CELL_WIDTH((keyboardWidth + gridWidth - 1) / gridWidth), CELL_HEIGHT((keyboardHeight + gridHeight - 1) / gridHeight), @@ -84,6 +86,7 @@ ProximityInfo::ProximityInfo(JNIEnv *env, const jstring localeJStr, const int ma safeGetOrFillZeroFloatArrayRegion(env, sweetSpotCenterYs, KEY_COUNT, mSweetSpotCenterYs); safeGetOrFillZeroFloatArrayRegion(env, sweetSpotRadii, KEY_COUNT, mSweetSpotRadii); initializeCodeToKeyIndex(); + initializeG(); } // Build the reversed look up table from the char code to the index in mKeyXCoordinates, @@ -222,6 +225,67 @@ int ProximityInfo::getKeyIndex(const int c) const { return mCodeToKeyIndex[baseLowerC]; } +int ProximityInfo::getKeyCode(const int keyIndex) const { + if (keyIndex < 0 || keyIndex >= KEY_COUNT) { + return NOT_AN_INDEX; + } + return mKeyToCodeIndexG[keyIndex]; +} + +void ProximityInfo::initializeG() { + for (int i = 0; i < KEY_COUNT; ++i) { + const int code = mKeyCharCodes[i]; + const int lowerCode = toBaseLowerCase(code); + mCenterXsG[i] = mKeyXCoordinates[i] + mKeyWidths[i] / 2; + mCenterYsG[i] = mKeyYCoordinates[i] + mKeyHeights[i] / 2; + if (code != lowerCode && lowerCode >= 0 && lowerCode <= MAX_CHAR_CODE) { + mCodeToKeyIndex[lowerCode] = i; + mKeyToCodeIndexG[i] = lowerCode; + } else { + mKeyToCodeIndexG[i] = code; + } + } + for (int i = 0; i < KEY_COUNT; i++) { + mKeyKeyDistancesG[i][i] = 0; + for (int j = i + 1; j < KEY_COUNT; j++) { + mKeyKeyDistancesG[i][j] = getDistance( + mCenterXsG[i], mCenterYsG[i], mCenterXsG[j], mCenterYsG[j]); + mKeyKeyDistancesG[j][i] = mKeyKeyDistancesG[i][j]; + } + } +} + +float ProximityInfo::getKeyCenterXOfCharG(int charCode) const { + return getKeyCenterXOfIdG(getKeyIndex(charCode)); +} + +float ProximityInfo::getKeyCenterYOfCharG(int charCode) const { + return getKeyCenterYOfIdG(getKeyIndex(charCode)); +} + +float ProximityInfo::getKeyCenterXOfIdG(int keyId) const { + if (keyId >= 0) { + return mCenterXsG[keyId]; + } + return 0; +} + +float ProximityInfo::getKeyCenterYOfIdG(int keyId) const { + if (keyId >= 0) { + return mCenterYsG[keyId]; + } + return 0; +} + +int ProximityInfo::getKeyKeyDistanceG(int key0, int key1) const { + const int keyId0 = getKeyIndex(key0); + const int keyId1 = getKeyIndex(key1); + if (keyId0 >= 0 && keyId1 >= 0) { + return mKeyKeyDistancesG[keyId0][keyId1]; + } + return 0; +} + // TODO: [Staging] Optimize void ProximityInfo::getCenters(int *centerXs, int *centerYs, int *codeToKeyIndex, int *keyToCodeIndex, int *keyCount, int *keyWidth) const { diff --git a/native/jni/src/proximity_info.h b/native/jni/src/proximity_info.h index d7e24c5f5..58f2d7502 100644 --- a/native/jni/src/proximity_info.h +++ b/native/jni/src/proximity_info.h @@ -49,6 +49,7 @@ class ProximityInfo { return left < right && top < bottom && x >= left && x < right && y >= top && y < bottom; } int getKeyIndex(const int c) const; + int getKeyCode(const int keyIndex) const; bool hasSweetSpotData(const int keyIndex) const { // When there are no calibration data for a key, // the radius of the key is assigned to zero. @@ -70,6 +71,10 @@ class ProximityInfo { return HAS_TOUCH_POSITION_CORRECTION_DATA; } + int getMostCommonKeyWidth() const { + return MOST_COMMON_KEY_WIDTH; + } + int getMostCommonKeyWidthSquare() const { return MOST_COMMON_KEY_WIDTH_SQUARE; } @@ -98,6 +103,12 @@ class ProximityInfo { return GRID_HEIGHT; } + float getKeyCenterXOfCharG(int charCode) const; + float getKeyCenterYOfCharG(int charCode) const; + float getKeyCenterXOfIdG(int keyId) const; + float getKeyCenterYOfIdG(int keyId) const; + int getKeyKeyDistanceG(int key0, int key1) const; + // Returns the keyboard key-center information. void getCenters(int *centersX, int *centersY, int *codeToKeyIndex, int *keyToCodeIndex, int *keyCount, int *keyWidth) const; @@ -113,6 +124,7 @@ class ProximityInfo { int getStartIndexFromCoordinates(const int x, const int y) const; void initializeCodeToKeyIndex(); + void initializeG(); float calculateNormalizedSquaredDistance(const int keyIndex, const int inputIndex) const; float calculateSquaredDistanceFromSweetSpotCenter( const int keyIndex, const int inputIndex) const; @@ -123,6 +135,7 @@ class ProximityInfo { const int KEYBOARD_HEIGHT; const int GRID_WIDTH; const int GRID_HEIGHT; + const int MOST_COMMON_KEY_WIDTH; const int MOST_COMMON_KEY_WIDTH_SQUARE; const int CELL_WIDTH; const int CELL_HEIGHT; @@ -139,6 +152,11 @@ class ProximityInfo { float mSweetSpotCenterYs[MAX_KEY_COUNT_IN_A_KEYBOARD]; float mSweetSpotRadii[MAX_KEY_COUNT_IN_A_KEYBOARD]; int mCodeToKeyIndex[MAX_CHAR_CODE + 1]; + + int mKeyToCodeIndexG[MAX_KEY_COUNT_IN_A_KEYBOARD]; + int mCenterXsG[MAX_KEY_COUNT_IN_A_KEYBOARD]; + int mCenterYsG[MAX_KEY_COUNT_IN_A_KEYBOARD]; + int mKeyKeyDistancesG[MAX_KEY_COUNT_IN_A_KEYBOARD][MAX_KEY_COUNT_IN_A_KEYBOARD]; // TODO: move to correction.h }; } // namespace latinime diff --git a/native/jni/src/unigram_dictionary.cpp b/native/jni/src/unigram_dictionary.cpp index b6b0210cc..9f7ab5362 100644 --- a/native/jni/src/unigram_dictionary.cpp +++ b/native/jni/src/unigram_dictionary.cpp @@ -63,8 +63,8 @@ static inline unsigned int getCodesBufferSize(const int *codes, const int codesS // TODO: This needs to take a const unsigned short* and not tinker with its contents static inline void addWord( - unsigned short *word, int length, int frequency, WordsPriorityQueue *queue) { - queue->push(frequency, word, length); + unsigned short *word, int length, int frequency, WordsPriorityQueue *queue, int type) { + queue->push(frequency, word, length, type); } // Return the replacement code point for a digraph, or 0 if none. @@ -213,8 +213,8 @@ int UnigramDictionary::getSuggestions(ProximityInfo *proximityInfo, AKLOGI("Max normalized score = %f", ns); } const int suggestedWordsCount = - queuePool.getMasterQueue()->outputSuggestions( - masterCorrection.getPrimaryInputWord(), codesSize, frequencies, outWords); + queuePool.getMasterQueue()->outputSuggestions(masterCorrection.getPrimaryInputWord(), + codesSize, frequencies, outWords, outputTypes); if (DEBUG_DICT) { float ns = queuePool.getMasterQueue()->getHighestNormalizedScore( @@ -391,7 +391,8 @@ inline void UnigramDictionary::onTerminal(const int probability, const int finalProbability = correction->getFinalProbability(probability, &wordPointer, &wordLength); if (finalProbability != NOT_A_PROBABILITY) { - addWord(wordPointer, wordLength, finalProbability, masterQueue); + addWord(wordPointer, wordLength, finalProbability, masterQueue, + Dictionary::KIND_CORRECTION); const int shortcutProbability = finalProbability > 0 ? finalProbability - 1 : 0; // Please note that the shortcut candidates will be added to the master queue only. @@ -409,7 +410,7 @@ inline void UnigramDictionary::onTerminal(const int probability, const int shortcutTargetStringLength = iterator.getNextShortcutTarget( MAX_WORD_LENGTH_INTERNAL, shortcutTarget); addWord(shortcutTarget, shortcutTargetStringLength, shortcutProbability, - masterQueue); + masterQueue, Dictionary::KIND_CORRECTION); } } } @@ -424,7 +425,7 @@ inline void UnigramDictionary::onTerminal(const int probability, } const int finalProbability = correction->getFinalProbabilityForSubQueue( probability, &wordPointer, &wordLength, inputIndex); - addWord(wordPointer, wordLength, finalProbability, subQueue); + addWord(wordPointer, wordLength, finalProbability, subQueue, Dictionary::KIND_CORRECTION); } } @@ -572,7 +573,8 @@ int UnigramDictionary::getSubStringSuggestion( AKLOGI("Split two words: freq = %d, length = %d, %d, isSpace ? %d", pairFreq, inputLength, tempOutputWordLength, isSpaceProximity); } - addWord(outputWord, tempOutputWordLength, pairFreq, queuePool->getMasterQueue()); + addWord(outputWord, tempOutputWordLength, pairFreq, queuePool->getMasterQueue(), + Dictionary::KIND_CORRECTION); } return FLAG_MULTIPLE_SUGGEST_CONTINUE; } diff --git a/native/jni/src/words_priority_queue.h b/native/jni/src/words_priority_queue.h index c0dedb59d..8a6da1c95 100644 --- a/native/jni/src/words_priority_queue.h +++ b/native/jni/src/words_priority_queue.h @@ -33,12 +33,14 @@ class WordsPriorityQueue { unsigned short mWord[MAX_WORD_LENGTH_INTERNAL]; int mWordLength; bool mUsed; + int mType; - void setParams(int score, unsigned short *word, int wordLength) { + void setParams(int score, unsigned short *word, int wordLength, int type) { mScore = score; mWordLength = wordLength; memcpy(mWord, word, sizeof(unsigned short) * wordLength); mUsed = true; + mType = type; } }; @@ -56,7 +58,7 @@ class WordsPriorityQueue { delete[] mSuggestedWords; } - void push(int score, unsigned short *word, int wordLength) { + void push(int score, unsigned short *word, int wordLength, int type) { SuggestedWord *sw = 0; if (mSuggestions.size() >= MAX_WORDS) { sw = mSuggestions.top(); @@ -69,9 +71,9 @@ class WordsPriorityQueue { } } if (sw == 0) { - sw = getFreeSuggestedWord(score, word, wordLength); + sw = getFreeSuggestedWord(score, word, wordLength, type); } else { - sw->setParams(score, word, wordLength); + sw->setParams(score, word, wordLength, type); } if (sw == 0) { AKLOGE("SuggestedWord is accidentally null."); @@ -94,7 +96,7 @@ class WordsPriorityQueue { } int outputSuggestions(const unsigned short *before, const int beforeLength, - int *frequencies, unsigned short *outputChars) { + int *frequencies, unsigned short *outputChars, int* outputTypes) { mHighestSuggestedWord = 0; const unsigned int size = min( MAX_WORDS, static_cast<unsigned int>(mSuggestions.size())); @@ -140,6 +142,7 @@ class WordsPriorityQueue { const unsigned int wordLength = sw->mWordLength; char *targetAdr = (char*) outputChars + i * MAX_WORD_LENGTH * sizeof(short); frequencies[i] = sw->mScore; + outputTypes[i] = sw->mType; memcpy(targetAdr, sw->mWord, (wordLength) * sizeof(short)); if (wordLength < MAX_WORD_LENGTH) { ((unsigned short*) targetAdr)[wordLength] = 0; @@ -191,10 +194,10 @@ class WordsPriorityQueue { }; SuggestedWord *getFreeSuggestedWord(int score, unsigned short *word, - int wordLength) { + int wordLength, int type) { for (unsigned int i = 0; i < MAX_WORD_LENGTH; ++i) { if (!mSuggestedWords[i].mUsed) { - mSuggestedWords[i].setParams(score, word, wordLength); + mSuggestedWords[i].setParams(score, word, wordLength, type); return &mSuggestedWords[i]; } } |