aboutsummaryrefslogtreecommitdiffstats
path: root/native
diff options
context:
space:
mode:
Diffstat (limited to 'native')
-rw-r--r--native/jni/Android.mk5
-rw-r--r--native/jni/com_android_inputmethod_keyboard_ProximityInfo.cpp54
-rw-r--r--native/jni/com_android_inputmethod_latin_BinaryDictionary.cpp234
-rw-r--r--native/jni/com_android_inputmethod_latin_DicTraverseSession.cpp63
-rw-r--r--native/jni/com_android_inputmethod_latin_DicTraverseSession.h (renamed from native/jni/com_android_inputmethod_latin_NativeUtils.h)11
-rw-r--r--native/jni/jni_common.cpp16
-rw-r--r--native/jni/jni_common.h27
-rw-r--r--native/jni/src/additional_proximity_chars.cpp4
-rw-r--r--native/jni/src/additional_proximity_chars.h23
-rw-r--r--native/jni/src/bigram_dictionary.cpp14
-rw-r--r--native/jni/src/binary_format.h7
-rw-r--r--native/jni/src/char_utils.cpp8
-rw-r--r--native/jni/src/correction.cpp14
-rw-r--r--native/jni/src/correction.h1
-rw-r--r--native/jni/src/debug.h7
-rw-r--r--native/jni/src/defines.h3
-rw-r--r--native/jni/src/dic_traverse_wrapper.cpp (renamed from native/jni/com_android_inputmethod_latin_NativeUtils.cpp)24
-rw-r--r--native/jni/src/dic_traverse_wrapper.h66
-rw-r--r--native/jni/src/dictionary.cpp25
-rw-r--r--native/jni/src/dictionary.h19
-rw-r--r--native/jni/src/geometry_utils.h98
-rw-r--r--native/jni/src/gesture/gesture_decoder_wrapper.h32
-rw-r--r--native/jni/src/gesture/incremental_decoder_interface.h14
-rw-r--r--native/jni/src/gesture/incremental_decoder_wrapper.h32
-rw-r--r--native/jni/src/proximity_info.cpp152
-rw-r--r--native/jni/src/proximity_info.h38
-rw-r--r--native/jni/src/proximity_info_state.h30
-rw-r--r--native/jni/src/terminal_attributes.h3
-rw-r--r--native/jni/src/unigram_dictionary.cpp37
-rw-r--r--native/jni/src/words_priority_queue.h27
30 files changed, 685 insertions, 403 deletions
diff --git a/native/jni/Android.mk b/native/jni/Android.mk
index 9f9958377..567648f7a 100644
--- a/native/jni/Android.mk
+++ b/native/jni/Android.mk
@@ -36,7 +36,7 @@ LOCAL_CFLAGS += -Wno-unused-parameter -Wno-unused-function
LATIN_IME_JNI_SRC_FILES := \
com_android_inputmethod_keyboard_ProximityInfo.cpp \
com_android_inputmethod_latin_BinaryDictionary.cpp \
- com_android_inputmethod_latin_NativeUtils.cpp \
+ com_android_inputmethod_latin_DicTraverseSession.cpp \
jni_common.cpp
LATIN_IME_CORE_SRC_FILES := \
@@ -46,6 +46,7 @@ LATIN_IME_CORE_SRC_FILES := \
char_utils.cpp \
correction.cpp \
dictionary.cpp \
+ dic_traverse_wrapper.cpp \
proximity_info.cpp \
proximity_info_state.cpp \
unigram_dictionary.cpp \
@@ -69,7 +70,6 @@ endif # FLAG_DO_PROFILE
LOCAL_MODULE := libjni_latinime_common_static
LOCAL_MODULE_TAGS := optional
-LOCAL_NDK_VERSION := 8
LOCAL_SDK_VERSION := 14
LOCAL_NDK_STL_VARIANT := stlport_static
@@ -93,7 +93,6 @@ endif # FLAG_DO_PROFILE
LOCAL_MODULE := libjni_latinime
LOCAL_MODULE_TAGS := optional
-LOCAL_NDK_VERSION := 8
LOCAL_SDK_VERSION := 14
LOCAL_NDK_STL_VARIANT := stlport_static
diff --git a/native/jni/com_android_inputmethod_keyboard_ProximityInfo.cpp b/native/jni/com_android_inputmethod_keyboard_ProximityInfo.cpp
index 74390ccdf..560b3a533 100644
--- a/native/jni/com_android_inputmethod_keyboard_ProximityInfo.cpp
+++ b/native/jni/com_android_inputmethod_keyboard_ProximityInfo.cpp
@@ -16,8 +16,6 @@
#define LOG_TAG "LatinIME: jni: ProximityInfo"
-#include <string>
-
#include "com_android_inputmethod_keyboard_ProximityInfo.h"
#include "jni.h"
#include "jni_common.h"
@@ -26,53 +24,27 @@
namespace latinime {
static jlong latinime_Keyboard_setProximityInfo(JNIEnv *env, jobject object,
- jstring localejStr, jint maxProximityCharsSize, jint displayWidth, jint displayHeight,
- jint gridWidth, jint gridHeight, jint mostCommonkeyWidth, jintArray proximityCharsArray,
- jint keyCount, jintArray keyXCoordinateArray, jintArray keyYCoordinateArray,
- jintArray keyWidthArray, jintArray keyHeightArray, jintArray keyCharCodeArray,
- jfloatArray sweetSpotCenterXArray, jfloatArray sweetSpotCenterYArray,
- jfloatArray sweetSpotRadiusArray) {
- const char *localeStrPtr = env->GetStringUTFChars(localejStr, 0);
- const std::string localeStr(localeStrPtr);
- jint *proximityChars = env->GetIntArrayElements(proximityCharsArray, 0);
- jint *keyXCoordinates = safeGetIntArrayElements(env, keyXCoordinateArray);
- jint *keyYCoordinates = safeGetIntArrayElements(env, keyYCoordinateArray);
- jint *keyWidths = safeGetIntArrayElements(env, keyWidthArray);
- jint *keyHeights = safeGetIntArrayElements(env, keyHeightArray);
- jint *keyCharCodes = safeGetIntArrayElements(env, keyCharCodeArray);
- jfloat *sweetSpotCenterXs = safeGetFloatArrayElements(env, sweetSpotCenterXArray);
- jfloat *sweetSpotCenterYs = safeGetFloatArrayElements(env, sweetSpotCenterYArray);
- jfloat *sweetSpotRadii = safeGetFloatArrayElements(env, sweetSpotRadiusArray);
- ProximityInfo *proximityInfo = new ProximityInfo(
- localeStr, maxProximityCharsSize, displayWidth, displayHeight, gridWidth, gridHeight,
- mostCommonkeyWidth, (const int32_t*)proximityChars, keyCount,
- (const int32_t*)keyXCoordinates, (const int32_t*)keyYCoordinates,
- (const int32_t*)keyWidths, (const int32_t*)keyHeights, (const int32_t*)keyCharCodes,
- (const float*)sweetSpotCenterXs, (const float*)sweetSpotCenterYs,
- (const float*)sweetSpotRadii);
- safeReleaseFloatArrayElements(env, sweetSpotRadiusArray, sweetSpotRadii);
- safeReleaseFloatArrayElements(env, sweetSpotCenterYArray, sweetSpotCenterYs);
- safeReleaseFloatArrayElements(env, sweetSpotCenterXArray, sweetSpotCenterXs);
- safeReleaseIntArrayElements(env, keyCharCodeArray, keyCharCodes);
- safeReleaseIntArrayElements(env, keyHeightArray, keyHeights);
- safeReleaseIntArrayElements(env, keyWidthArray, keyWidths);
- safeReleaseIntArrayElements(env, keyYCoordinateArray, keyYCoordinates);
- safeReleaseIntArrayElements(env, keyXCoordinateArray, keyXCoordinates);
- env->ReleaseIntArrayElements(proximityCharsArray, proximityChars, 0);
- env->ReleaseStringUTFChars(localejStr, localeStrPtr);
- return (jlong)proximityInfo;
+ jstring localeJStr, jint maxProximityCharsSize, jint displayWidth, jint displayHeight,
+ jint gridWidth, jint gridHeight, jint mostCommonkeyWidth, jintArray proximityChars,
+ jint keyCount, jintArray keyXCoordinates, jintArray keyYCoordinates,
+ jintArray keyWidths, jintArray keyHeights, jintArray keyCharCodes,
+ jfloatArray sweetSpotCenterXs, jfloatArray sweetSpotCenterYs, jfloatArray sweetSpotRadii) {
+ ProximityInfo *proximityInfo = new ProximityInfo(env, localeJStr, maxProximityCharsSize,
+ displayWidth, displayHeight, gridWidth, gridHeight, mostCommonkeyWidth, proximityChars,
+ keyCount, keyXCoordinates, keyYCoordinates, keyWidths, keyHeights, keyCharCodes,
+ sweetSpotCenterXs, sweetSpotCenterYs, sweetSpotRadii);
+ return reinterpret_cast<jlong>(proximityInfo);
}
static void latinime_Keyboard_release(JNIEnv *env, jobject object, jlong proximityInfo) {
- ProximityInfo *pi = (ProximityInfo*)proximityInfo;
- if (!pi) return;
+ ProximityInfo *pi = reinterpret_cast<ProximityInfo *>(proximityInfo);
delete pi;
}
static JNINativeMethod sKeyboardMethods[] = {
{"setProximityInfoNative", "(Ljava/lang/String;IIIIII[II[I[I[I[I[I[F[F[F)J",
- (void*)latinime_Keyboard_setProximityInfo},
- {"releaseProximityInfoNative", "(J)V", (void*)latinime_Keyboard_release}
+ reinterpret_cast<void *>(latinime_Keyboard_setProximityInfo)},
+ {"releaseProximityInfoNative", "(J)V", reinterpret_cast<void *>(latinime_Keyboard_release)}
};
int register_ProximityInfo(JNIEnv *env) {
diff --git a/native/jni/com_android_inputmethod_latin_BinaryDictionary.cpp b/native/jni/com_android_inputmethod_latin_BinaryDictionary.cpp
index 776f5f78f..2add7c995 100644
--- a/native/jni/com_android_inputmethod_latin_BinaryDictionary.cpp
+++ b/native/jni/com_android_inputmethod_latin_BinaryDictionary.cpp
@@ -14,15 +14,12 @@
* limitations under the License.
*/
+
+#include <cstring> // for memset()
+
#define LOG_TAG "LatinIME: jni: BinaryDictionary"
-#include "binary_format.h"
-#include "com_android_inputmethod_latin_BinaryDictionary.h"
-#include "correction.h"
-#include "defines.h"
-#include "dictionary.h"
-#include "jni.h"
-#include "jni_common.h"
+#include "defines.h" // for macros below
#ifdef USE_MMAP_FOR_DICTIONARY
#include <cerrno>
@@ -30,13 +27,21 @@
#include <sys/mman.h>
#else // USE_MMAP_FOR_DICTIONARY
#include <cstdlib>
+#include <cstdio> // for fopen() etc.
#endif // USE_MMAP_FOR_DICTIONARY
+#include "binary_format.h"
+#include "com_android_inputmethod_latin_BinaryDictionary.h"
+#include "correction.h"
+#include "dictionary.h"
+#include "jni.h"
+#include "jni_common.h"
+
namespace latinime {
class ProximityInfo;
-void releaseDictBuf(void *dictBuf, const size_t length, int fd);
+static void releaseDictBuf(const void *dictBuf, const size_t length, const int fd);
static jlong latinime_BinaryDictionary_open(JNIEnv *env, jobject object,
jstring sourceDir, jlong dictOffset, jlong dictSize,
@@ -44,11 +49,14 @@ static jlong latinime_BinaryDictionary_open(JNIEnv *env, jobject object,
jint maxPredictions) {
PROF_OPEN;
PROF_START(66);
- const char *sourceDirChars = env->GetStringUTFChars(sourceDir, 0);
- if (sourceDirChars == 0) {
+ const jsize sourceDirUtf8Length = env->GetStringUTFLength(sourceDir);
+ if (sourceDirUtf8Length <= 0) {
AKLOGE("DICT: Can't get sourceDir string");
return 0;
}
+ char sourceDirChars[sourceDirUtf8Length + 1];
+ env->GetStringUTFRegion(sourceDir, 0, env->GetStringLength(sourceDir), sourceDirChars);
+ sourceDirChars[sourceDirUtf8Length] = '\0';
int fd = 0;
void *dictBuf = 0;
int adjust = 0;
@@ -68,7 +76,7 @@ static jlong latinime_BinaryDictionary_open(JNIEnv *env, jobject object,
AKLOGE("DICT: Can't mmap dictionary. errno=%d", errno);
return 0;
}
- dictBuf = (void *)((char *)dictBuf + adjust);
+ dictBuf = static_cast<char *>(dictBuf) + adjust;
#else // USE_MMAP_FOR_DICTIONARY
/* malloc version */
FILE *file = 0;
@@ -98,17 +106,16 @@ static jlong latinime_BinaryDictionary_open(JNIEnv *env, jobject object,
return 0;
}
#endif // USE_MMAP_FOR_DICTIONARY
- env->ReleaseStringUTFChars(sourceDir, sourceDirChars);
-
if (!dictBuf) {
AKLOGE("DICT: dictBuf is null");
return 0;
}
Dictionary *dictionary = 0;
- if (BinaryFormat::UNKNOWN_FORMAT == BinaryFormat::detectFormat((uint8_t*)dictBuf)) {
+ if (BinaryFormat::UNKNOWN_FORMAT
+ == BinaryFormat::detectFormat(static_cast<uint8_t *>(dictBuf))) {
AKLOGE("DICT: dictionary format is unknown, bad magic number");
#ifdef USE_MMAP_FOR_DICTIONARY
- releaseDictBuf(((char*)dictBuf) - adjust, adjDictSize, fd);
+ releaseDictBuf(static_cast<const char *>(dictBuf) - adjust, adjDictSize, fd);
#else // USE_MMAP_FOR_DICTIONARY
releaseDictBuf(dictBuf, 0, 0);
#endif // USE_MMAP_FOR_DICTIONARY
@@ -122,106 +129,131 @@ static jlong latinime_BinaryDictionary_open(JNIEnv *env, jobject object,
}
static int latinime_BinaryDictionary_getSuggestions(JNIEnv *env, jobject object, jlong dict,
- jlong proximityInfo, jintArray xCoordinatesArray, jintArray yCoordinatesArray,
- jintArray timesArray, jintArray pointerIdArray, jintArray inputArray, jint arraySize,
- jint commitPoint, jboolean isGesture,
- jintArray prevWordForBigrams, jboolean useFullEditDistance, jcharArray outputArray,
- jintArray frequencyArray, jintArray spaceIndexArray, jintArray outputTypesArray) {
- Dictionary *dictionary = (Dictionary*) dict;
+ jlong proximityInfo, jlong dicTraverseSession, jintArray xCoordinatesArray,
+ jintArray yCoordinatesArray, jintArray timesArray, jintArray pointerIdsArray,
+ jintArray inputCodePointsArray, jint arraySize, jint commitPoint, jboolean isGesture,
+ jintArray prevWordCodePointsForBigrams, jboolean useFullEditDistance,
+ jcharArray outputCharsArray, jintArray scoresArray, jintArray spaceIndicesArray,
+ jintArray outputTypesArray) {
+ Dictionary *dictionary = reinterpret_cast<Dictionary *>(dict);
if (!dictionary) return 0;
- ProximityInfo *pInfo = (ProximityInfo*)proximityInfo;
- int *xCoordinates = env->GetIntArrayElements(xCoordinatesArray, 0);
- int *yCoordinates = env->GetIntArrayElements(yCoordinatesArray, 0);
- int *times = env->GetIntArrayElements(timesArray, 0);
- int *pointerIds = env->GetIntArrayElements(pointerIdArray, 0);
- int *frequencies = env->GetIntArrayElements(frequencyArray, 0);
- int *inputCodes = env->GetIntArrayElements(inputArray, 0);
- jchar *outputChars = env->GetCharArrayElements(outputArray, 0);
- int *spaceIndices = env->GetIntArrayElements(spaceIndexArray, 0);
- int *outputTypes = env->GetIntArrayElements(outputTypesArray, 0);
- jint *prevWordChars = prevWordForBigrams
- ? env->GetIntArrayElements(prevWordForBigrams, 0) : 0;
- jsize prevWordLength = prevWordChars ? env->GetArrayLength(prevWordForBigrams) : 0;
+ ProximityInfo *pInfo = reinterpret_cast<ProximityInfo *>(proximityInfo);
+ void *traverseSession = reinterpret_cast<void *>(dicTraverseSession);
+
+ // Input values
+ int xCoordinates[arraySize];
+ int yCoordinates[arraySize];
+ int times[arraySize];
+ int pointerIds[arraySize];
+ const jsize inputCodePointsLength = env->GetArrayLength(inputCodePointsArray);
+ int inputCodePoints[inputCodePointsLength];
+ const jsize prevWordCodePointsLength =
+ prevWordCodePointsForBigrams ? env->GetArrayLength(prevWordCodePointsForBigrams) : 0;
+ int prevWordCodePointsInternal[prevWordCodePointsLength];
+ int *prevWordCodePoints = 0;
+ env->GetIntArrayRegion(xCoordinatesArray, 0, arraySize, xCoordinates);
+ env->GetIntArrayRegion(yCoordinatesArray, 0, arraySize, yCoordinates);
+ env->GetIntArrayRegion(timesArray, 0, arraySize, times);
+ env->GetIntArrayRegion(pointerIdsArray, 0, arraySize, pointerIds);
+ env->GetIntArrayRegion(inputCodePointsArray, 0, inputCodePointsLength, inputCodePoints);
+ if (prevWordCodePointsForBigrams) {
+ env->GetIntArrayRegion(prevWordCodePointsForBigrams, 0, prevWordCodePointsLength,
+ prevWordCodePointsInternal);
+ prevWordCodePoints = prevWordCodePointsInternal;
+ }
+
+ // Output values
+ // TODO: Should be "outputCodePointsLength" and "int outputCodePoints[]"
+ const jsize outputCharsLength = env->GetArrayLength(outputCharsArray);
+ unsigned short outputChars[outputCharsLength];
+ const jsize scoresLength = env->GetArrayLength(scoresArray);
+ int scores[scoresLength];
+ const jsize spaceIndicesLength = env->GetArrayLength(spaceIndicesArray);
+ int spaceIndices[spaceIndicesLength];
+ const jsize outputTypesLength = env->GetArrayLength(outputTypesArray);
+ int outputTypes[outputTypesLength];
+ memset(outputChars, 0, outputCharsLength * sizeof(outputChars[0]));
+ memset(scores, 0, scoresLength * sizeof(scores[0]));
+ memset(spaceIndices, 0, spaceIndicesLength * sizeof(spaceIndices[0]));
+ memset(outputTypes, 0, outputTypesLength * sizeof(outputTypes[0]));
int count;
if (isGesture || arraySize > 1) {
- count = dictionary->getSuggestions(pInfo, xCoordinates, yCoordinates, times, pointerIds,
- inputCodes, arraySize, prevWordChars, prevWordLength, commitPoint, isGesture,
- useFullEditDistance, (unsigned short*) outputChars, frequencies, spaceIndices,
- outputTypes);
+ count = dictionary->getSuggestions(pInfo, traverseSession, xCoordinates, yCoordinates,
+ times, pointerIds, inputCodePoints, arraySize, prevWordCodePoints,
+ prevWordCodePointsLength, commitPoint, isGesture, useFullEditDistance, outputChars,
+ scores, spaceIndices, outputTypes);
} else {
- count = dictionary->getBigrams(prevWordChars, prevWordLength, inputCodes,
- arraySize, (unsigned short*) outputChars, frequencies, outputTypes);
+ count = dictionary->getBigrams(prevWordCodePoints, prevWordCodePointsLength,
+ inputCodePoints, arraySize, outputChars, scores, outputTypes);
}
- if (prevWordChars) {
- env->ReleaseIntArrayElements(prevWordForBigrams, prevWordChars, JNI_ABORT);
- }
- env->ReleaseIntArrayElements(outputTypesArray, outputTypes, 0);
- env->ReleaseIntArrayElements(spaceIndexArray, spaceIndices, 0);
- env->ReleaseCharArrayElements(outputArray, outputChars, 0);
- env->ReleaseIntArrayElements(inputArray, inputCodes, JNI_ABORT);
- env->ReleaseIntArrayElements(frequencyArray, frequencies, 0);
- env->ReleaseIntArrayElements(pointerIdArray, pointerIds, 0);
- env->ReleaseIntArrayElements(timesArray, times, 0);
- env->ReleaseIntArrayElements(yCoordinatesArray, yCoordinates, 0);
- env->ReleaseIntArrayElements(xCoordinatesArray, xCoordinates, 0);
+ // Copy back the output values
+ // TODO: Should be SetIntArrayRegion()
+ env->SetCharArrayRegion(outputCharsArray, 0, outputCharsLength, outputChars);
+ env->SetIntArrayRegion(scoresArray, 0, scoresLength, scores);
+ env->SetIntArrayRegion(spaceIndicesArray, 0, spaceIndicesLength, spaceIndices);
+ env->SetIntArrayRegion(outputTypesArray, 0, outputTypesLength, outputTypes);
+
return count;
}
static jint latinime_BinaryDictionary_getFrequency(JNIEnv *env, jobject object, jlong dict,
- jintArray wordArray, jint wordLength) {
- Dictionary *dictionary = (Dictionary*)dict;
- if (!dictionary) return (jboolean) false;
- jint *word = env->GetIntArrayElements(wordArray, 0);
- jint result = dictionary->getFrequency(word, wordLength);
- env->ReleaseIntArrayElements(wordArray, word, JNI_ABORT);
- return result;
+ jintArray wordArray) {
+ Dictionary *dictionary = reinterpret_cast<Dictionary *>(dict);
+ if (!dictionary) return 0;
+ const jsize codePointLength = env->GetArrayLength(wordArray);
+ int codePoints[codePointLength];
+ env->GetIntArrayRegion(wordArray, 0, codePointLength, codePoints);
+ return dictionary->getFrequency(codePoints, codePointLength);
}
static jboolean latinime_BinaryDictionary_isValidBigram(JNIEnv *env, jobject object, jlong dict,
jintArray wordArray1, jintArray wordArray2) {
- Dictionary *dictionary = (Dictionary*)dict;
+ Dictionary *dictionary = reinterpret_cast<Dictionary *>(dict);
if (!dictionary) return (jboolean) false;
- jint *word1 = env->GetIntArrayElements(wordArray1, 0);
- jint *word2 = env->GetIntArrayElements(wordArray2, 0);
- jsize length1 = word1 ? env->GetArrayLength(wordArray1) : 0;
- jsize length2 = word2 ? env->GetArrayLength(wordArray2) : 0;
- jboolean result = dictionary->isValidBigram(word1, length1, word2, length2);
- env->ReleaseIntArrayElements(wordArray2, word2, JNI_ABORT);
- env->ReleaseIntArrayElements(wordArray1, word1, JNI_ABORT);
- return result;
+ const jsize codePointLength1 = env->GetArrayLength(wordArray1);
+ const jsize codePointLength2 = env->GetArrayLength(wordArray2);
+ int codePoints1[codePointLength1];
+ int codePoints2[codePointLength2];
+ env->GetIntArrayRegion(wordArray1, 0, codePointLength1, codePoints1);
+ env->GetIntArrayRegion(wordArray2, 0, codePointLength2, codePoints2);
+ return dictionary->isValidBigram(codePoints1, codePointLength1, codePoints2, codePointLength2);
}
static jfloat latinime_BinaryDictionary_calcNormalizedScore(JNIEnv *env, jobject object,
- jcharArray before, jint beforeLength, jcharArray after, jint afterLength, jint score) {
- jchar *beforeChars = env->GetCharArrayElements(before, 0);
- jchar *afterChars = env->GetCharArrayElements(after, 0);
- jfloat result = Correction::RankingAlgorithm::calcNormalizedScore((unsigned short*)beforeChars,
- beforeLength, (unsigned short*)afterChars, afterLength, score);
- env->ReleaseCharArrayElements(after, afterChars, JNI_ABORT);
- env->ReleaseCharArrayElements(before, beforeChars, JNI_ABORT);
- return result;
+ jcharArray before, jcharArray after, jint score) {
+ jsize beforeLength = env->GetArrayLength(before);
+ jsize afterLength = env->GetArrayLength(after);
+ jchar beforeChars[beforeLength];
+ jchar afterChars[afterLength];
+ env->GetCharArrayRegion(before, 0, beforeLength, beforeChars);
+ env->GetCharArrayRegion(after, 0, afterLength, afterChars);
+ return Correction::RankingAlgorithm::calcNormalizedScore(
+ static_cast<unsigned short *>(beforeChars), beforeLength,
+ static_cast<unsigned short *>(afterChars), afterLength, score);
}
static jint latinime_BinaryDictionary_editDistance(JNIEnv *env, jobject object,
- jcharArray before, jint beforeLength, jcharArray after, jint afterLength) {
- jchar *beforeChars = env->GetCharArrayElements(before, 0);
- jchar *afterChars = env->GetCharArrayElements(after, 0);
- jint result = Correction::RankingAlgorithm::editDistance(
- (unsigned short*)beforeChars, beforeLength, (unsigned short*)afterChars, afterLength);
- env->ReleaseCharArrayElements(after, afterChars, JNI_ABORT);
- env->ReleaseCharArrayElements(before, beforeChars, JNI_ABORT);
- return result;
+ jcharArray before, jcharArray after) {
+ jsize beforeLength = env->GetArrayLength(before);
+ jsize afterLength = env->GetArrayLength(after);
+ jchar beforeChars[beforeLength];
+ jchar afterChars[afterLength];
+ env->GetCharArrayRegion(before, 0, beforeLength, beforeChars);
+ env->GetCharArrayRegion(after, 0, afterLength, afterChars);
+ return Correction::RankingAlgorithm::editDistance(
+ static_cast<unsigned short *>(beforeChars), beforeLength,
+ static_cast<unsigned short *>(afterChars), afterLength);
}
static void latinime_BinaryDictionary_close(JNIEnv *env, jobject object, jlong dict) {
- Dictionary *dictionary = (Dictionary*)dict;
+ Dictionary *dictionary = reinterpret_cast<Dictionary *>(dict);
if (!dictionary) return;
- void *dictBuf = dictionary->getDict();
+ const void *dictBuf = dictionary->getDict();
if (!dictBuf) return;
#ifdef USE_MMAP_FOR_DICTIONARY
- releaseDictBuf((void *)((char *)dictBuf - dictionary->getDictBufAdjust()),
+ releaseDictBuf(static_cast<const char *>(dictBuf) - dictionary->getDictBufAdjust(),
dictionary->getDictSize() + dictionary->getDictBufAdjust(), dictionary->getMmapFd());
#else // USE_MMAP_FOR_DICTIONARY
releaseDictBuf(dictBuf, 0, 0);
@@ -229,9 +261,9 @@ static void latinime_BinaryDictionary_close(JNIEnv *env, jobject object, jlong d
delete dictionary;
}
-void releaseDictBuf(void *dictBuf, const size_t length, int fd) {
+static void releaseDictBuf(const void *dictBuf, const size_t length, const int fd) {
#ifdef USE_MMAP_FOR_DICTIONARY
- int ret = munmap(dictBuf, length);
+ int ret = munmap(const_cast<void *>(dictBuf), length);
if (ret != 0) {
AKLOGE("DICT: Failure in munmap. ret=%d errno=%d", ret, errno);
}
@@ -240,20 +272,24 @@ void releaseDictBuf(void *dictBuf, const size_t length, int fd) {
AKLOGE("DICT: Failure in close. ret=%d errno=%d", ret, errno);
}
#else // USE_MMAP_FOR_DICTIONARY
- free(dictBuf);
+ free(const_cast<void *>(dictBuf));
#endif // USE_MMAP_FOR_DICTIONARY
}
static JNINativeMethod sMethods[] = {
- {"openNative", "(Ljava/lang/String;JJIIIII)J", (void*)latinime_BinaryDictionary_open},
- {"closeNative", "(J)V", (void*)latinime_BinaryDictionary_close},
- {"getSuggestionsNative", "(JJ[I[I[I[I[IIIZ[IZ[C[I[I[I)I",
- (void*) latinime_BinaryDictionary_getSuggestions},
- {"getFrequencyNative", "(J[II)I", (void*)latinime_BinaryDictionary_getFrequency},
- {"isValidBigramNative", "(J[I[I)Z", (void*)latinime_BinaryDictionary_isValidBigram},
- {"calcNormalizedScoreNative", "([CI[CII)F",
- (void*)latinime_BinaryDictionary_calcNormalizedScore},
- {"editDistanceNative", "([CI[CI)I", (void*)latinime_BinaryDictionary_editDistance}
+ {"openNative", "(Ljava/lang/String;JJIIIII)J",
+ reinterpret_cast<void *>(latinime_BinaryDictionary_open)},
+ {"closeNative", "(J)V", reinterpret_cast<void *>(latinime_BinaryDictionary_close)},
+ {"getSuggestionsNative", "(JJJ[I[I[I[I[IIIZ[IZ[C[I[I[I)I",
+ reinterpret_cast<void *>(latinime_BinaryDictionary_getSuggestions)},
+ {"getFrequencyNative", "(J[I)I",
+ reinterpret_cast<void *>(latinime_BinaryDictionary_getFrequency)},
+ {"isValidBigramNative", "(J[I[I)Z",
+ reinterpret_cast<void *>(latinime_BinaryDictionary_isValidBigram)},
+ {"calcNormalizedScoreNative", "([C[CI)F",
+ reinterpret_cast<void *>(latinime_BinaryDictionary_calcNormalizedScore)},
+ {"editDistanceNative", "([C[C)I",
+ reinterpret_cast<void *>(latinime_BinaryDictionary_editDistance)}
};
int register_BinaryDictionary(JNIEnv *env) {
diff --git a/native/jni/com_android_inputmethod_latin_DicTraverseSession.cpp b/native/jni/com_android_inputmethod_latin_DicTraverseSession.cpp
new file mode 100644
index 000000000..5d405f117
--- /dev/null
+++ b/native/jni/com_android_inputmethod_latin_DicTraverseSession.cpp
@@ -0,0 +1,63 @@
+/*
+ * 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 "com_android_inputmethod_latin_DicTraverseSession.h"
+#include "dic_traverse_wrapper.h"
+#include "jni.h"
+#include "jni_common.h"
+
+namespace latinime {
+class Dictionary;
+static jlong latinime_setDicTraverseSession(JNIEnv *env, jobject object, jstring localeJStr) {
+ void *traverseSession = DicTraverseWrapper::getDicTraverseSession(env, localeJStr);
+ return reinterpret_cast<jlong>(traverseSession);
+}
+
+static void latinime_initDicTraverseSession(JNIEnv *env, jobject object, jlong traverseSession,
+ jlong dictionary, jintArray previousWord, jint previousWordLength) {
+ void *ts = reinterpret_cast<void *>(traverseSession);
+ Dictionary *dict = reinterpret_cast<Dictionary *>(dictionary);
+ if (!previousWord) {
+ DicTraverseWrapper::initDicTraverseSession(ts, dict, 0, 0);
+ return;
+ }
+ int prevWord[previousWordLength];
+ env->GetIntArrayRegion(previousWord, 0, previousWordLength, prevWord);
+ DicTraverseWrapper::initDicTraverseSession(ts, dict, prevWord, previousWordLength);
+}
+
+static void latinime_releaseDicTraverseSession(JNIEnv *env, jobject object, jlong traverseSession) {
+ void *ts = reinterpret_cast<void *>(traverseSession);
+ DicTraverseWrapper::releaseDicTraverseSession(ts);
+}
+
+static JNINativeMethod sMethods[] = {
+ {"setDicTraverseSessionNative", "(Ljava/lang/String;)J",
+ reinterpret_cast<void *>(latinime_setDicTraverseSession)},
+ {"initDicTraverseSessionNative", "(JJ[II)V",
+ reinterpret_cast<void *>(latinime_initDicTraverseSession)},
+ {"releaseDicTraverseSessionNative", "(J)V",
+ reinterpret_cast<void *>(latinime_releaseDicTraverseSession)}
+};
+
+int register_DicTraverseSession(JNIEnv *env) {
+ const char *const kClassPathName = "com/android/inputmethod/latin/DicTraverseSession";
+ return registerNativeMethods(env, kClassPathName, sMethods,
+ sizeof(sMethods) / sizeof(sMethods[0]));
+}
+} // namespace latinime
diff --git a/native/jni/com_android_inputmethod_latin_NativeUtils.h b/native/jni/com_android_inputmethod_latin_DicTraverseSession.h
index d1ffb8f4a..37531e96b 100644
--- a/native/jni/com_android_inputmethod_latin_NativeUtils.h
+++ b/native/jni/com_android_inputmethod_latin_DicTraverseSession.h
@@ -14,14 +14,13 @@
* limitations under the License.
*/
-#ifndef _COM_ANDROID_INPUTMETHOD_LATIN_NATIVEUTILS_H
-#define _COM_ANDROID_INPUTMETHOD_LATIN_NATIVEUTILS_H
+#ifndef _COM_ANDROID_INPUTMETHOD_LATIN_DICTRAVERSESESSION_H
+#define _COM_ANDROID_INPUTMETHOD_LATIN_DICTRAVERSESESSION_H
+#include "defines.h"
#include "jni.h"
namespace latinime {
-
-int register_NativeUtils(JNIEnv *env);
-
+int register_DicTraverseSession(JNIEnv *env);
} // namespace latinime
-#endif // _COM_ANDROID_INPUTMETHOD_LATIN_NATIVEUTILS_H
+#endif // _COM_ANDROID_INPUTMETHOD_LATIN_DICTRAVERSESESSION_H
diff --git a/native/jni/jni_common.cpp b/native/jni/jni_common.cpp
index 105a4dc4c..0da166903 100644
--- a/native/jni/jni_common.cpp
+++ b/native/jni/jni_common.cpp
@@ -16,15 +16,15 @@
#define LOG_TAG "LatinIME: jni"
+#include <cassert>
+
#include "com_android_inputmethod_keyboard_ProximityInfo.h"
#include "com_android_inputmethod_latin_BinaryDictionary.h"
-#include "com_android_inputmethod_latin_NativeUtils.h"
+#include "com_android_inputmethod_latin_DicTraverseSession.h"
#include "defines.h"
#include "jni.h"
#include "jni_common.h"
-#include <cassert>
-
using namespace latinime;
/*
@@ -34,7 +34,7 @@ jint JNI_OnLoad(JavaVM *vm, void *reserved) {
JNIEnv *env = 0;
jint result = -1;
- if (vm->GetEnv(reinterpret_cast<void**>(&env), JNI_VERSION_1_6) != JNI_OK) {
+ if (vm->GetEnv(reinterpret_cast<void **>(&env), JNI_VERSION_1_6) != JNI_OK) {
AKLOGE("ERROR: GetEnv failed");
goto bail;
}
@@ -45,13 +45,13 @@ jint JNI_OnLoad(JavaVM *vm, void *reserved) {
goto bail;
}
- if (!register_ProximityInfo(env)) {
- AKLOGE("ERROR: ProximityInfo native registration failed");
+ if (!register_DicTraverseSession(env)) {
+ AKLOGE("ERROR: DicTraverseSession native registration failed");
goto bail;
}
- if (!register_NativeUtils(env)) {
- AKLOGE("ERROR: NativeUtils native registration failed");
+ if (!register_ProximityInfo(env)) {
+ AKLOGE("ERROR: ProximityInfo native registration failed");
goto bail;
}
diff --git a/native/jni/jni_common.h b/native/jni/jni_common.h
index 658ff18b9..993f97e80 100644
--- a/native/jni/jni_common.h
+++ b/native/jni/jni_common.h
@@ -24,32 +24,5 @@ namespace latinime {
int registerNativeMethods(JNIEnv *env, const char *className, JNINativeMethod *methods,
int numMethods);
-inline jint *safeGetIntArrayElements(JNIEnv *env, jintArray jArray) {
- if (jArray) {
- return env->GetIntArrayElements(jArray, 0);
- } else {
- return 0;
- }
-}
-
-inline jfloat *safeGetFloatArrayElements(JNIEnv *env, jfloatArray jArray) {
- if (jArray) {
- return env->GetFloatArrayElements(jArray, 0);
- } else {
- return 0;
- }
-}
-
-inline void safeReleaseIntArrayElements(JNIEnv *env, jintArray jArray, jint *cArray) {
- if (jArray) {
- env->ReleaseIntArrayElements(jArray, cArray, 0);
- }
-}
-
-inline void safeReleaseFloatArrayElements(JNIEnv *env, jfloatArray jArray, jfloat *cArray) {
- if (jArray) {
- env->ReleaseFloatArrayElements(jArray, cArray, 0);
- }
-}
} // namespace latinime
#endif // LATINIME_JNI_COMMON_H
diff --git a/native/jni/src/additional_proximity_chars.cpp b/native/jni/src/additional_proximity_chars.cpp
index de8764678..f59492741 100644
--- a/native/jni/src/additional_proximity_chars.cpp
+++ b/native/jni/src/additional_proximity_chars.cpp
@@ -17,7 +17,9 @@
#include "additional_proximity_chars.h"
namespace latinime {
-const std::string AdditionalProximityChars::LOCALE_EN_US("en");
+// TODO: Stop using hardcoded additional proximity characters.
+// TODO: Have proximity character informations in each language's binary dictionary.
+const char *AdditionalProximityChars::LOCALE_EN_US = "en";
const int32_t AdditionalProximityChars::EN_US_ADDITIONAL_A[EN_US_ADDITIONAL_A_SIZE] = {
'e', 'i', 'o', 'u'
diff --git a/native/jni/src/additional_proximity_chars.h b/native/jni/src/additional_proximity_chars.h
index ba76cfced..1fe996d0d 100644
--- a/native/jni/src/additional_proximity_chars.h
+++ b/native/jni/src/additional_proximity_chars.h
@@ -17,8 +17,8 @@
#ifndef LATINIME_ADDITIONAL_PROXIMITY_CHARS_H
#define LATINIME_ADDITIONAL_PROXIMITY_CHARS_H
+#include <cstring>
#include <stdint.h>
-#include <string>
#include "defines.h"
@@ -27,7 +27,7 @@ namespace latinime {
class AdditionalProximityChars {
private:
DISALLOW_IMPLICIT_CONSTRUCTORS(AdditionalProximityChars);
- static const std::string LOCALE_EN_US;
+ static const char *LOCALE_EN_US;
static const int EN_US_ADDITIONAL_A_SIZE = 4;
static const int32_t EN_US_ADDITIONAL_A[];
static const int EN_US_ADDITIONAL_E_SIZE = 4;
@@ -39,14 +39,15 @@ class AdditionalProximityChars {
static const int EN_US_ADDITIONAL_U_SIZE = 4;
static const int32_t EN_US_ADDITIONAL_U[];
- static bool isEnLocale(const std::string *locale_str) {
- return locale_str && locale_str->size() >= LOCALE_EN_US.size()
- && LOCALE_EN_US.compare(0, LOCALE_EN_US.size(), *locale_str);
+ static bool isEnLocale(const char *localeStr) {
+ const size_t LOCALE_EN_US_SIZE = strlen(LOCALE_EN_US);
+ return localeStr && strlen(localeStr) >= LOCALE_EN_US_SIZE
+ && strncmp(localeStr, LOCALE_EN_US, LOCALE_EN_US_SIZE) == 0;
}
public:
- static int getAdditionalCharsSize(const std::string *locale_str, const int32_t c) {
- if (!isEnLocale(locale_str)) {
+ static int getAdditionalCharsSize(const char *localeStr, const int32_t c) {
+ if (!isEnLocale(localeStr)) {
return 0;
}
switch(c) {
@@ -65,8 +66,8 @@ class AdditionalProximityChars {
}
}
- static const int32_t *getAdditionalChars(const std::string *locale_str, const int32_t c) {
- if (!isEnLocale(locale_str)) {
+ static const int32_t *getAdditionalChars(const char *localeStr, const int32_t c) {
+ if (!isEnLocale(localeStr)) {
return 0;
}
switch(c) {
@@ -84,10 +85,6 @@ class AdditionalProximityChars {
return 0;
}
}
-
- static bool hasAdditionalChars(const std::string *locale_str, const int32_t c) {
- return getAdditionalCharsSize(locale_str, c) > 0;
- }
};
} // namespace latinime
#endif // LATINIME_ADDITIONAL_PROXIMITY_CHARS_H
diff --git a/native/jni/src/bigram_dictionary.cpp b/native/jni/src/bigram_dictionary.cpp
index 220171127..f1d538095 100644
--- a/native/jni/src/bigram_dictionary.cpp
+++ b/native/jni/src/bigram_dictionary.cpp
@@ -60,15 +60,15 @@ bool BigramDictionary::addWordBigram(unsigned short *word, int length, int frequ
AKLOGI("Bigram: InsertAt -> %d MAX_PREDICTIONS: %d", insertAt, MAX_PREDICTIONS);
}
if (insertAt < MAX_PREDICTIONS) {
- memmove((char*) bigramFreq + (insertAt + 1) * sizeof(bigramFreq[0]),
- (char*) bigramFreq + insertAt * sizeof(bigramFreq[0]),
- (MAX_PREDICTIONS - insertAt - 1) * sizeof(bigramFreq[0]));
+ memmove(bigramFreq + (insertAt + 1),
+ bigramFreq + insertAt,
+ (MAX_PREDICTIONS - insertAt - 1) * sizeof(bigramFreq[0]));
bigramFreq[insertAt] = frequency;
outputTypes[insertAt] = Dictionary::KIND_PREDICTION;
- memmove((char*) bigramChars + (insertAt + 1) * MAX_WORD_LENGTH * sizeof(short),
- (char*) bigramChars + (insertAt ) * MAX_WORD_LENGTH * sizeof(short),
- (MAX_PREDICTIONS - insertAt - 1) * sizeof(short) * MAX_WORD_LENGTH);
- unsigned short *dest = bigramChars + (insertAt ) * MAX_WORD_LENGTH;
+ memmove(bigramChars + (insertAt + 1) * MAX_WORD_LENGTH,
+ bigramChars + insertAt * MAX_WORD_LENGTH,
+ (MAX_PREDICTIONS - insertAt - 1) * sizeof(bigramChars[0]) * MAX_WORD_LENGTH);
+ unsigned short *dest = bigramChars + insertAt * MAX_WORD_LENGTH;
while (length--) {
*dest++ = *word++;
}
diff --git a/native/jni/src/binary_format.h b/native/jni/src/binary_format.h
index 2ee4077c1..4cabc8404 100644
--- a/native/jni/src/binary_format.h
+++ b/native/jni/src/binary_format.h
@@ -52,6 +52,8 @@ class BinaryFormat {
// Mask for attribute frequency, stored on 4 bits inside the flags byte.
static const int MASK_ATTRIBUTE_FREQUENCY = 0x0F;
+ // The numeric value of the shortcut frequency that means 'whitelist'.
+ static const int WHITELIST_SHORTCUT_FREQUENCY = 15;
// Mask and flags for attribute address type selection.
static const int MASK_ATTRIBUTE_ADDRESS_TYPE = 0x30;
@@ -99,6 +101,7 @@ class BinaryFormat {
static bool hasChildrenInFlags(const uint8_t flags);
static int getAttributeAddressAndForwardPointer(const uint8_t *const dict, const uint8_t flags,
int *pos);
+ static int getAttributeFrequencyFromFlags(const int flags);
static int getTerminalPosition(const uint8_t *const root, const int32_t *const inWord,
const int length, const bool forceLowerCaseSearch);
static int getWordAtAddress(const uint8_t *const root, const int address, const int maxDepth,
@@ -340,6 +343,10 @@ inline int BinaryFormat::getAttributeAddressAndForwardPointer(const uint8_t *con
}
}
+inline int BinaryFormat::getAttributeFrequencyFromFlags(const int flags) {
+ return flags & MASK_ATTRIBUTE_FREQUENCY;
+}
+
// This function gets the byte position of the last chargroup of the exact matching word in the
// dictionary. If no match is found, it returns NOT_VALID_WORD.
inline int BinaryFormat::getTerminalPosition(const uint8_t *const root,
diff --git a/native/jni/src/char_utils.cpp b/native/jni/src/char_utils.cpp
index 45d49b087..223291f60 100644
--- a/native/jni/src/char_utils.cpp
+++ b/native/jni/src/char_utils.cpp
@@ -885,16 +885,16 @@ static const struct LatinCapitalSmallPair SORTED_CHAR_MAP[] = {
};
static int compare_pair_capital(const void *a, const void *b) {
- return (int)(*(unsigned short *)a)
- - (int)((struct LatinCapitalSmallPair*)b)->capital;
+ return static_cast<int>(*static_cast<const unsigned short *>(a))
+ - static_cast<int>((static_cast<const struct LatinCapitalSmallPair *>(b))->capital);
}
unsigned short latin_tolower(unsigned short c) {
struct LatinCapitalSmallPair *p =
- (struct LatinCapitalSmallPair *)bsearch(&c, SORTED_CHAR_MAP,
+ static_cast<struct LatinCapitalSmallPair *>(bsearch(&c, SORTED_CHAR_MAP,
sizeof(SORTED_CHAR_MAP) / sizeof(SORTED_CHAR_MAP[0]),
sizeof(SORTED_CHAR_MAP[0]),
- compare_pair_capital);
+ compare_pair_capital));
return p ? p->small : c;
}
} // namespace latinime
diff --git a/native/jni/src/correction.cpp b/native/jni/src/correction.cpp
index ea4bddae2..e55da0113 100644
--- a/native/jni/src/correction.cpp
+++ b/native/jni/src/correction.cpp
@@ -154,11 +154,13 @@ void Correction::checkState() {
if (mSkipPos >= 0) ++inputCount;
if (mExcessivePos >= 0) ++inputCount;
if (mTransposedPos >= 0) ++inputCount;
- // TODO: remove this assert
- assert(inputCount <= 1);
}
}
+bool Correction::sameAsTyped() {
+ return mProximityInfoState.sameAsTyped(mWord, mOutputIndex);
+}
+
int Correction::getFreqForSplitMultipleWords(const int *freqArray, const int *wordLengthArray,
const int wordCount, const bool isSpaceProximity, const unsigned short *word) {
return Correction::RankingAlgorithm::calcFreqForSplitMultipleWords(freqArray, wordLengthArray,
@@ -1094,7 +1096,7 @@ int Correction::RankingAlgorithm::editDistance(const unsigned short *before,
// In dictionary.cpp, getSuggestion() method,
// suggestion scores are computed using the below formula.
// original score
-// := pow(mTypedLetterMultiplier (this is defined 2),
+// := powf(mTypedLetterMultiplier (this is defined 2),
// (the number of matched characters between typed word and suggested word))
// * (individual word's score which defined in the unigram dictionary,
// and this score is defined in range [0, 255].)
@@ -1106,11 +1108,11 @@ int Correction::RankingAlgorithm::editDistance(const unsigned short *before,
// capitalization, then treat it as if the score was 255.
// - If before.length() == after.length()
// => multiply by mFullWordMultiplier (this is defined 2))
-// So, maximum original score is pow(2, min(before.length(), after.length())) * 255 * 2 * 1.2
+// So, maximum original score is powf(2, min(before.length(), after.length())) * 255 * 2 * 1.2
// For historical reasons we ignore the 1.2 modifier (because the measure for a good
// autocorrection threshold was done at a time when it didn't exist). This doesn't change
// the result.
-// So, we can normalize original score by dividing pow(2, min(b.l(),a.l())) * 255 * 2.
+// So, we can normalize original score by dividing powf(2, min(b.l(),a.l())) * 255 * 2.
/* static */
float Correction::RankingAlgorithm::calcNormalizedScore(const unsigned short *before,
@@ -1132,7 +1134,7 @@ float Correction::RankingAlgorithm::calcNormalizedScore(const unsigned short *be
}
const float maxScore = score >= S_INT_MAX ? S_INT_MAX : MAX_INITIAL_SCORE
- * pow(static_cast<float>(TYPED_LETTER_MULTIPLIER),
+ * powf(static_cast<float>(TYPED_LETTER_MULTIPLIER),
static_cast<float>(min(beforeLength, afterLength - spaceCount)))
* FULL_WORD_MULTIPLIER;
diff --git a/native/jni/src/correction.h b/native/jni/src/correction.h
index 81623a46b..57e7b7189 100644
--- a/native/jni/src/correction.h
+++ b/native/jni/src/correction.h
@@ -105,6 +105,7 @@ class Correction {
const int spaceProximityPos, const int missingSpacePos, const bool useFullEditDistance,
const bool doAutoCompletion, const int maxErrors);
void checkState();
+ bool sameAsTyped();
bool initProcessState(const int index);
int getInputIndex();
diff --git a/native/jni/src/debug.h b/native/jni/src/debug.h
index 2168d6672..4e2164014 100644
--- a/native/jni/src/debug.h
+++ b/native/jni/src/debug.h
@@ -58,11 +58,12 @@ static inline void LOGI_S16_PLUS(unsigned short *string, const unsigned int leng
}
static inline void printDebug(const char *tag, int *codes, int codesSize, int MAX_PROXIMITY_CHARS) {
- unsigned char *buf = (unsigned char*)malloc((1 + codesSize) * sizeof(*buf));
+ unsigned char *buf = static_cast<unsigned char *>(malloc((1 + codesSize) * sizeof(*buf)));
buf[codesSize] = 0;
- while (--codesSize >= 0)
- buf[codesSize] = (unsigned char)codes[codesSize * MAX_PROXIMITY_CHARS];
+ while (--codesSize >= 0) {
+ buf[codesSize] = static_cast<unsigned char>(codes[codesSize * MAX_PROXIMITY_CHARS]);
+ }
AKLOGI("%s, WORD = %s", tag, buf);
free(buf);
diff --git a/native/jni/src/defines.h b/native/jni/src/defines.h
index 31dd61e30..484fc6bde 100644
--- a/native/jni/src/defines.h
+++ b/native/jni/src/defines.h
@@ -265,6 +265,9 @@ static inline void prof_out(void) {
// This must be equal to ADDITIONAL_PROXIMITY_CHAR_DELIMITER_CODE in KeyDetector.java
#define ADDITIONAL_PROXIMITY_CHAR_DELIMITER_CODE 2
+// Assuming locale strings such as en_US, sr-Latn etc.
+#define MAX_LOCALE_STRING_LENGTH 10
+
// Word limit for sub queues used in WordsPriorityQueuePool. Sub queues are temporary queues used
// for better performance.
// Holds up to 1 candidate for each word
diff --git a/native/jni/com_android_inputmethod_latin_NativeUtils.cpp b/native/jni/src/dic_traverse_wrapper.cpp
index 8f1afbeb6..1f7dcbfb2 100644
--- a/native/jni/com_android_inputmethod_latin_NativeUtils.cpp
+++ b/native/jni/src/dic_traverse_wrapper.cpp
@@ -14,25 +14,13 @@
* limitations under the License.
*/
-#include "com_android_inputmethod_latin_NativeUtils.h"
-#include "jni.h"
-#include "jni_common.h"
+#define LOG_TAG "LatinIME: jni: Session"
-#include <cmath>
+#include "dic_traverse_wrapper.h"
namespace latinime {
-
-static float latinime_NativeUtils_powf(float x, float y) {
- return powf(x, y);
-}
-
-static JNINativeMethod sMethods[] = {
- {"powf", "(FF)F", (void*)latinime_NativeUtils_powf}
-};
-
-int register_NativeUtils(JNIEnv *env) {
- const char *const kClassPathName = "com/android/inputmethod/latin/NativeUtils";
- return registerNativeMethods(env, kClassPathName, sMethods,
- sizeof(sMethods) / sizeof(sMethods[0]));
-}
+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 ee55cfa60..158c3fb22 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(static_cast<unsigned char *>(dict)),
+ mOffsetDict((static_cast<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,11 @@ 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 */);
}
Dictionary::~Dictionary() {
@@ -56,16 +55,18 @@ Dictionary::~Dictionary() {
delete mGestureDecoder;
}
-int Dictionary::getSuggestions(ProximityInfo *proximityInfo, int *xcoordinates, int *ycoordinates,
- int *times, int *pointerIds, int *codes, int codesSize, int *prevWordChars,
+int Dictionary::getSuggestions(ProximityInfo *proximityInfo, void *traverseSession,
+ int *xcoordinates, int *ycoordinates, int *times, int *pointerIds,
+ int *codes, int codesSize, int *prevWordChars,
int prevWordLength, int commitPoint, bool isGesture,
bool useFullEditDistance, unsigned short *outWords,
int *frequencies, int *spaceIndices, int *outputTypes) {
int result = 0;
if (isGesture) {
- mGestureDecoder->setPrevWord(prevWordChars, prevWordLength);
- result = mGestureDecoder->getSuggestions(proximityInfo, xcoordinates, ycoordinates,
- times, pointerIds, codes, codesSize, commitPoint,
+ DicTraverseWrapper::initDicTraverseSession(
+ traverseSession, this, prevWordChars, prevWordLength);
+ result = mGestureDecoder->getSuggestions(proximityInfo, traverseSession,
+ xcoordinates, ycoordinates, times, pointerIds, codes, codesSize, commitPoint,
outWords, frequencies, spaceIndices, outputTypes);
if (DEBUG_DICT) {
DUMP_RESULT(outWords, frequencies, 18 /* MAX_WORDS */, MAX_WORD_LENGTH_INTERNAL);
diff --git a/native/jni/src/dictionary.h b/native/jni/src/dictionary.h
index ab238c824..fd9e77011 100644
--- a/native/jni/src/dictionary.h
+++ b/native/jni/src/dictionary.h
@@ -44,9 +44,9 @@ class Dictionary {
Dictionary(void *dict, int dictSize, int mmapFd, int dictBufAdjust, int typedLetterMultipler,
int fullWordMultiplier, int maxWordLength, int maxWords, int maxPredictions);
- int getSuggestions(ProximityInfo *proximityInfo, int *xcoordinates, int *ycoordinates,
- int *times, int *pointerIds, int *codes, int codesSize, int *prevWordChars,
- int prevWordLength, int commitPoint, bool isGesture,
+ int getSuggestions(ProximityInfo *proximityInfo, void *traverseSession, int *xcoordinates,
+ int *ycoordinates, int *times, int *pointerIds, int *codes, int codesSize,
+ int *prevWordChars, int prevWordLength, int commitPoint, bool isGesture,
bool useFullEditDistance, unsigned short *outWords,
int *frequencies, int *spaceIndices, int *outputTypes);
@@ -55,7 +55,12 @@ 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; }
+ const uint8_t *getDict() const { // required to release dictionary buffer
+ return mDict;
+ }
+ const uint8_t *getOffsetDict() const {
+ return mOffsetDict;
+ }
int getDictSize() const { return mDictSize; }
int getMmapFd() const { return mMmapFd; }
int getDictBufAdjust() const { return mDictBufAdjust; }
@@ -67,7 +72,8 @@ class Dictionary {
private:
DISALLOW_IMPLICIT_CONSTRUCTORS(Dictionary);
- const unsigned char *mDict;
+ const uint8_t *mDict;
+ const uint8_t *mOffsetDict;
// Used only for the mmap version of dictionary loading, but we use these as dummy variables
// also for the malloc version.
@@ -85,8 +91,9 @@ class Dictionary {
inline int Dictionary::wideStrLen(unsigned short *str) {
if (!str) return 0;
unsigned short *end = str;
- while (*end)
+ while (*end) {
end++;
+ }
return end - str;
}
} // namespace latinime
diff --git a/native/jni/src/geometry_utils.h b/native/jni/src/geometry_utils.h
new file mode 100644
index 000000000..146eb8055
--- /dev/null
+++ b/native/jni/src/geometry_utils.h
@@ -0,0 +1,98 @@
+/*
+ * 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_GEOMETRY_UTILS_H
+#define LATINIME_GEOMETRY_UTILS_H
+
+#include <cmath>
+
+#define MAX_DISTANCE 10000000
+#define MAX_PATHS 2
+
+#define DEBUG_DECODER false
+
+#define M_PI_F 3.14159265f
+
+namespace latinime {
+
+static inline float squareFloat(float x) {
+ return x * x;
+}
+
+static inline float getSquaredDistanceFloat(float x1, float y1, float x2, float y2) {
+ return squareFloat(x1 - x2) + squareFloat(y1 - y2);
+}
+
+static inline float getDistanceFloat(float x1, float y1, float x2, float y2) {
+ return hypotf(x1 - x2, y1 - y2);
+}
+
+static inline int getDistanceInt(int x1, int y1, int x2, int y2) {
+ return static_cast<int>(getDistanceFloat(static_cast<float>(x1), static_cast<float>(y1),
+ static_cast<float>(x2), static_cast<float>(y2)));
+}
+
+static inline float getAngle(int x1, int y1, int x2, int y2) {
+ const int dx = x1 - x2;
+ const int dy = y1 - y2;
+ if (dx == 0 && dy == 0) return 0;
+ return atan2f(static_cast<float>(dy), static_cast<float>(dx));
+}
+
+static inline float getAngleDiff(float a1, float a2) {
+ const float diff = fabsf(a1 - a2);
+ if (diff > M_PI_F) {
+ return 2.0f * M_PI_F - diff;
+ }
+ return diff;
+}
+
+// static float pointToLineSegSquaredDistanceFloat(
+// 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 fabsf(A * D - C * B) / sqrtf(C * C + D * D);
+// }
+
+static inline float pointToLineSegSquaredDistanceFloat(
+ float x, float y, float x1, float y1, float x2, float y2) {
+ const float ray1x = x - x1;
+ const float ray1y = y - y1;
+ const float ray2x = x2 - x1;
+ const float ray2y = y2 - y1;
+
+ const float dotProduct = ray1x * ray2x + ray1y * ray2y;
+ const float lineLengthSqr = squareFloat(ray2x) + squareFloat(ray2y);
+ const float projectionLengthSqr = dotProduct / lineLengthSqr;
+
+ float projectionX;
+ float projectionY;
+ if (projectionLengthSqr < 0.0f) {
+ projectionX = x1;
+ projectionY = y1;
+ } else if (projectionLengthSqr > 1.0f) {
+ projectionX = x2;
+ projectionY = y2;
+ } else {
+ projectionX = x1 + projectionLengthSqr * ray2x;
+ projectionY = y1 + projectionLengthSqr * ray2y;
+ }
+ return getSquaredDistanceFloat(x, y, projectionX, projectionY);
+}
+} // namespace latinime
+#endif // LATINIME_GEOMETRY_UTILS_H
diff --git a/native/jni/src/gesture/gesture_decoder_wrapper.h b/native/jni/src/gesture/gesture_decoder_wrapper.h
index 03c84b5fd..f8bfe7c79 100644
--- a/native/jni/src/gesture/gesture_decoder_wrapper.h
+++ b/native/jni/src/gesture/gesture_decoder_wrapper.h
@@ -37,37 +37,15 @@ class GestureDecoderWrapper : public IncrementalDecoderInterface {
delete mIncrementalDecoderInterface;
}
- int getSuggestions(ProximityInfo *pInfo, int *inputXs, int *inputYs, int *times,
- int *pointerIds, int *codes, int inputSize, int commitPoint,
+ int getSuggestions(ProximityInfo *pInfo, void *traverseSession, int *inputXs, int *inputYs,
+ int *times, int *pointerIds, int *codes, int inputSize, int commitPoint,
unsigned short *outWords, int *frequencies, int *outputIndices, int *outputTypes) {
if (!mIncrementalDecoderInterface) {
return 0;
}
return mIncrementalDecoderInterface->getSuggestions(
- pInfo, inputXs, inputYs, times, pointerIds, codes, 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) {
- return;
- }
- mIncrementalDecoderInterface->setDict(dict, bigram, dictRoot, rootPos);
- }
-
- void setPrevWord(const int32_t *prevWord, int prevWordLength) {
- if (!mIncrementalDecoderInterface) {
- return;
- }
- mIncrementalDecoderInterface->setPrevWord(prevWord, prevWordLength);
+ pInfo, traverseSession, inputXs, inputYs, times, pointerIds, codes,
+ inputSize, commitPoint, outWords, frequencies, outputIndices, outputTypes);
}
static void setGestureDecoderFactoryMethod(
@@ -76,7 +54,7 @@ class GestureDecoderWrapper : public IncrementalDecoderInterface {
}
private:
- DISALLOW_COPY_AND_ASSIGN(GestureDecoderWrapper);
+ DISALLOW_IMPLICIT_CONSTRUCTORS(GestureDecoderWrapper);
static IncrementalDecoderInterface *getGestureDecoderInstance(int maxWordLength, int maxWords) {
if (sGestureDecoderFactoryMethod) {
return sGestureDecoderFactoryMethod(maxWordLength, maxWords);
diff --git a/native/jni/src/gesture/incremental_decoder_interface.h b/native/jni/src/gesture/incremental_decoder_interface.h
index 6d2e273da..04f0095e0 100644
--- a/native/jni/src/gesture/incremental_decoder_interface.h
+++ b/native/jni/src/gesture/incremental_decoder_interface.h
@@ -28,14 +28,14 @@ class ProximityInfo;
class IncrementalDecoderInterface {
public:
- virtual int getSuggestions(ProximityInfo *pInfo, 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 int getSuggestions(ProximityInfo *pInfo, void *traverseSession,
+ int *inputXs, int *inputYs, int *times, int *pointerIds, int *codes,
+ int inputSize, int commitPoint, unsigned short *outWords, int *frequencies,
+ int *outputIndices, int *outputTypes) = 0;
+ IncrementalDecoderInterface() { };
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 698061548..5cb2ee368 100644
--- a/native/jni/src/gesture/incremental_decoder_wrapper.h
+++ b/native/jni/src/gesture/incremental_decoder_wrapper.h
@@ -37,37 +37,15 @@ class IncrementalDecoderWrapper : public IncrementalDecoderInterface {
delete mIncrementalDecoderInterface;
}
- int getSuggestions(ProximityInfo *pInfo, int *inputXs, int *inputYs, int *times,
- int *pointerIds, int *codes, int inputSize, int commitPoint,
+ int getSuggestions(ProximityInfo *pInfo, void *traverseSession, int *inputXs, int *inputYs,
+ int *times, int *pointerIds, int *codes, int inputSize, int commitPoint,
unsigned short *outWords, int *frequencies, int *outputIndices, int *outputTypes) {
if (!mIncrementalDecoderInterface) {
return 0;
}
return mIncrementalDecoderInterface->getSuggestions(
- pInfo, inputXs, inputYs, times, pointerIds, codes, 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) {
- return;
- }
- mIncrementalDecoderInterface->setDict(dict, bigram, dictRoot, rootPos);
- }
-
- void setPrevWord(const int32_t *prevWord, int prevWordLength) {
- if (!mIncrementalDecoderInterface) {
- return;
- }
- mIncrementalDecoderInterface->setPrevWord(prevWord, prevWordLength);
+ pInfo, traverseSession, inputXs, inputYs, times, pointerIds, codes,
+ inputSize, commitPoint, outWords, frequencies, outputIndices, outputTypes);
}
static void setIncrementalDecoderFactoryMethod(
@@ -76,7 +54,7 @@ class IncrementalDecoderWrapper : public IncrementalDecoderInterface {
}
private:
- DISALLOW_COPY_AND_ASSIGN(IncrementalDecoderWrapper);
+ DISALLOW_IMPLICIT_CONSTRUCTORS(IncrementalDecoderWrapper);
static IncrementalDecoderInterface *getIncrementalDecoderInstance(int maxWordLength,
int maxWords) {
if (sIncrementalDecoderFactoryMethod) {
diff --git a/native/jni/src/proximity_info.cpp b/native/jni/src/proximity_info.cpp
index cee408d46..1b9bac0f0 100644
--- a/native/jni/src/proximity_info.cpp
+++ b/native/jni/src/proximity_info.cpp
@@ -17,62 +17,76 @@
#include <cassert>
#include <cmath>
#include <cstring>
-#include <string>
#define LOG_TAG "LatinIME: proximity_info.cpp"
#include "additional_proximity_chars.h"
#include "char_utils.h"
#include "defines.h"
+#include "geometry_utils.h"
+#include "jni.h"
#include "proximity_info.h"
namespace latinime {
-inline void copyOrFillZero(void *to, const void *from, size_t size) {
- if (from) {
- memcpy(to, from, size);
- } else {
- memset(to, 0, size);
+static inline void safeGetOrFillZeroIntArrayRegion(JNIEnv *env, jintArray jArray, jsize len,
+ jint *buffer) {
+ if (jArray && buffer) {
+ env->GetIntArrayRegion(jArray, 0, len, buffer);
+ } else if (buffer) {
+ memset(buffer, 0, len * sizeof(jint));
}
}
-ProximityInfo::ProximityInfo(const std::string localeStr, const int maxProximityCharsSize,
+static inline void safeGetOrFillZeroFloatArrayRegion(JNIEnv *env, jfloatArray jArray, jsize len,
+ jfloat *buffer) {
+ if (jArray && buffer) {
+ env->GetFloatArrayRegion(jArray, 0, len, buffer);
+ } else if (buffer) {
+ memset(buffer, 0, len * sizeof(jfloat));
+ }
+}
+
+ProximityInfo::ProximityInfo(JNIEnv *env, const jstring localeJStr, const int maxProximityCharsSize,
const int keyboardWidth, const int keyboardHeight, const int gridWidth,
- const int gridHeight, const int mostCommonKeyWidth,
- const int32_t *proximityCharsArray, const int keyCount, const int32_t *keyXCoordinates,
- const int32_t *keyYCoordinates, const int32_t *keyWidths, const int32_t *keyHeights,
- const int32_t *keyCharCodes, const float *sweetSpotCenterXs, const float *sweetSpotCenterYs,
- const float *sweetSpotRadii)
+ 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)
: 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),
KEY_COUNT(min(keyCount, MAX_KEY_COUNT_IN_A_KEYBOARD)),
HAS_TOUCH_POSITION_CORRECTION_DATA(keyCount > 0 && keyXCoordinates && keyYCoordinates
&& keyWidths && keyHeights && keyCharCodes && sweetSpotCenterXs
- && sweetSpotCenterYs && sweetSpotRadii),
- mLocaleStr(localeStr) {
+ && sweetSpotCenterYs && sweetSpotRadii) {
const int proximityGridLength = GRID_WIDTH * GRID_HEIGHT * MAX_PROXIMITY_CHARS_SIZE;
if (DEBUG_PROXIMITY_INFO) {
AKLOGI("Create proximity info array %d", proximityGridLength);
}
+ const jsize localeCStrUtf8Length = env->GetStringUTFLength(localeJStr);
+ if (localeCStrUtf8Length >= MAX_LOCALE_STRING_LENGTH) {
+ AKLOGI("Locale string length too long: length=%d", localeCStrUtf8Length);
+ assert(false);
+ }
+ memset(mLocaleStr, 0, sizeof(mLocaleStr));
+ env->GetStringUTFRegion(localeJStr, 0, env->GetStringLength(localeJStr), mLocaleStr);
mProximityCharsArray = new int32_t[proximityGridLength];
- memcpy(mProximityCharsArray, proximityCharsArray,
- proximityGridLength * sizeof(mProximityCharsArray[0]));
-
- copyOrFillZero(mKeyXCoordinates, keyXCoordinates, KEY_COUNT * sizeof(mKeyXCoordinates[0]));
- copyOrFillZero(mKeyYCoordinates, keyYCoordinates, KEY_COUNT * sizeof(mKeyYCoordinates[0]));
- copyOrFillZero(mKeyWidths, keyWidths, KEY_COUNT * sizeof(mKeyWidths[0]));
- copyOrFillZero(mKeyHeights, keyHeights, KEY_COUNT * sizeof(mKeyHeights[0]));
- copyOrFillZero(mKeyCharCodes, keyCharCodes, KEY_COUNT * sizeof(mKeyCharCodes[0]));
- copyOrFillZero(mSweetSpotCenterXs, sweetSpotCenterXs,
- KEY_COUNT * sizeof(mSweetSpotCenterXs[0]));
- copyOrFillZero(mSweetSpotCenterYs, sweetSpotCenterYs,
- KEY_COUNT * sizeof(mSweetSpotCenterYs[0]));
- copyOrFillZero(mSweetSpotRadii, sweetSpotRadii, KEY_COUNT * sizeof(mSweetSpotRadii[0]));
-
+ safeGetOrFillZeroIntArrayRegion(env, proximityChars, proximityGridLength, mProximityCharsArray);
+ safeGetOrFillZeroIntArrayRegion(env, keyXCoordinates, KEY_COUNT, mKeyXCoordinates);
+ safeGetOrFillZeroIntArrayRegion(env, keyYCoordinates, KEY_COUNT, mKeyYCoordinates);
+ safeGetOrFillZeroIntArrayRegion(env, keyWidths, KEY_COUNT, mKeyWidths);
+ safeGetOrFillZeroIntArrayRegion(env, keyHeights, KEY_COUNT, mKeyHeights);
+ safeGetOrFillZeroIntArrayRegion(env, keyCharCodes, KEY_COUNT, mKeyCharCodes);
+ safeGetOrFillZeroFloatArrayRegion(env, sweetSpotCenterXs, KEY_COUNT, mSweetSpotCenterXs);
+ 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,
@@ -121,6 +135,21 @@ bool ProximityInfo::hasSpaceProximity(const int x, const int y) const {
return false;
}
+static inline float getNormalizedSquaredDistanceFloat(float x1, float y1, float x2, float y2,
+ float scale) {
+ return squareFloat((x1 - x2) / scale) + squareFloat((y1 - y2) / scale);
+}
+
+float ProximityInfo::getNormalizedSquaredDistanceFromCenterFloat(
+ const int keyId, const int x, const int y) const {
+ const float centerX = static_cast<float>(getKeyCenterXOfIdG(keyId));
+ const float centerY = static_cast<float>(getKeyCenterYOfIdG(keyId));
+ const float touchX = static_cast<float>(x);
+ const float touchY = static_cast<float>(y);
+ const float keyWidth = static_cast<float>(getMostCommonKeyWidth());
+ return getNormalizedSquaredDistanceFloat(centerX, centerY, touchX, touchY, keyWidth);
+}
+
int ProximityInfo::squaredDistanceToEdge(const int keyId, const int x, const int y) const {
if (keyId < 0) return true; // NOT_A_ID is -1, but return whenever < 0 just in case
const int left = mKeyXCoordinates[keyId];
@@ -160,7 +189,7 @@ void ProximityInfo::calculateNearbyKeyCodes(
}
}
const int additionalProximitySize =
- AdditionalProximityChars::getAdditionalCharsSize(&mLocaleStr, primaryKey);
+ AdditionalProximityChars::getAdditionalCharsSize(mLocaleStr, primaryKey);
if (additionalProximitySize > 0) {
inputCodes[insertPos++] = ADDITIONAL_PROXIMITY_CHAR_DELIMITER_CODE;
if (insertPos >= MAX_PROXIMITY_CHARS_SIZE) {
@@ -171,7 +200,7 @@ void ProximityInfo::calculateNearbyKeyCodes(
}
const int32_t *additionalProximityChars =
- AdditionalProximityChars::getAdditionalChars(&mLocaleStr, primaryKey);
+ AdditionalProximityChars::getAdditionalChars(mLocaleStr, primaryKey);
for (int j = 0; j < additionalProximitySize; ++j) {
const int32_t ac = additionalProximityChars[j];
int k = 0;
@@ -211,24 +240,65 @@ int ProximityInfo::getKeyIndex(const int c) const {
return mCodeToKeyIndex[baseLowerC];
}
-// TODO: [Staging] Optimize
-void ProximityInfo::getCenters(int *centerXs, int *centerYs, int *codeToKeyIndex,
- int *keyToCodeIndex, int *keyCount, int *keyWidth) const {
- *keyCount = KEY_COUNT;
- *keyWidth = sqrt(static_cast<float>(MOST_COMMON_KEY_WIDTH_SQUARE));
+int ProximityInfo::getKeyCode(const int keyIndex) const {
+ if (keyIndex < 0 || keyIndex >= KEY_COUNT) {
+ return NOT_AN_INDEX;
+ }
+ return mKeyToCodeIndexG[keyIndex];
+}
+void ProximityInfo::initializeG() {
+ // TODO: Optimize
for (int i = 0; i < KEY_COUNT; ++i) {
const int code = mKeyCharCodes[i];
const int lowerCode = toBaseLowerCase(code);
- centerXs[i] = mKeyXCoordinates[i] + mKeyWidths[i] / 2;
- centerYs[i] = mKeyYCoordinates[i] + mKeyHeights[i] / 2;
- codeToKeyIndex[code] = i;
+ mCenterXsG[i] = mKeyXCoordinates[i] + mKeyWidths[i] / 2;
+ mCenterYsG[i] = mKeyYCoordinates[i] + mKeyHeights[i] / 2;
if (code != lowerCode && lowerCode >= 0 && lowerCode <= MAX_CHAR_CODE) {
- codeToKeyIndex[lowerCode] = i;
- keyToCodeIndex[i] = lowerCode;
+ mCodeToKeyIndex[lowerCode] = i;
+ mKeyToCodeIndexG[i] = lowerCode;
} else {
- keyToCodeIndex[i] = code;
+ 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] = getDistanceInt(
+ 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;
+}
} // namespace latinime
diff --git a/native/jni/src/proximity_info.h b/native/jni/src/proximity_info.h
index abd07dd3e..8a407e71a 100644
--- a/native/jni/src/proximity_info.h
+++ b/native/jni/src/proximity_info.h
@@ -18,9 +18,9 @@
#define LATINIME_PROXIMITY_INFO_H
#include <stdint.h>
-#include <string>
#include "defines.h"
+#include "jni.h"
namespace latinime {
@@ -28,16 +28,18 @@ class Correction;
class ProximityInfo {
public:
- ProximityInfo(const std::string localeStr, const int maxProximityCharsSize,
+ ProximityInfo(JNIEnv *env, const jstring localeJStr, const int maxProximityCharsSize,
const int keyboardWidth, const int keyboardHeight, const int gridWidth,
- const int gridHeight, const int mostCommonkeyWidth,
- const int32_t *proximityCharsArray, const int keyCount, const int32_t *keyXCoordinates,
- const int32_t *keyYCoordinates, const int32_t *keyWidths, const int32_t *keyHeights,
- const int32_t *keyCharCodes, const float *sweetSpotCenterXs,
- const float *sweetSpotCenterYs, const float *sweetSpotRadii);
+ 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);
~ProximityInfo();
bool hasSpaceProximity(const int x, const int y) const;
int getNormalizedSquaredDistance(const int inputIndex, const int proximityIndex) const;
+ float getNormalizedSquaredDistanceFromCenterFloat(
+ const int keyId, const int x, const int y) const;
bool sameAsTyped(const unsigned short *word, int length) const;
int squaredDistanceToEdge(const int keyId, const int x, const int y) const;
bool isOnKey(const int keyId, const int x, const int y) const {
@@ -49,6 +51,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,11 +73,15 @@ 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;
}
- std::string getLocaleStr() const {
+ const char *getLocaleStr() const {
return mLocaleStr;
}
@@ -98,6 +105,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 +126,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,12 +137,13 @@ 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;
const int KEY_COUNT;
const bool HAS_TOUCH_POSITION_CORRECTION_DATA;
- const std::string mLocaleStr;
+ char mLocaleStr[MAX_LOCALE_STRING_LENGTH];
int32_t *mProximityCharsArray;
int32_t mKeyXCoordinates[MAX_KEY_COUNT_IN_A_KEYBOARD];
int32_t mKeyYCoordinates[MAX_KEY_COUNT_IN_A_KEYBOARD];
@@ -139,6 +154,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/proximity_info_state.h b/native/jni/src/proximity_info_state.h
index 76d45516e..474c40757 100644
--- a/native/jni/src/proximity_info_state.h
+++ b/native/jni/src/proximity_info_state.h
@@ -160,6 +160,21 @@ class ProximityInfoState {
return mTouchPositionCorrectionEnabled;
}
+ inline bool sameAsTyped(const unsigned short *word, int length) const {
+ if (length != mInputLength) {
+ return false;
+ }
+ const int *inputCodes = mInputCodes;
+ while (length--) {
+ if (static_cast<unsigned int>(*inputCodes) != static_cast<unsigned int>(*word)) {
+ return false;
+ }
+ inputCodes += MAX_PROXIMITY_CHARS_SIZE_INTERNAL;
+ word++;
+ }
+ return true;
+ }
+
private:
DISALLOW_COPY_AND_ASSIGN(ProximityInfoState);
/////////////////////////////////////////
@@ -179,21 +194,6 @@ class ProximityInfoState {
return mInputXCoordinates && mInputYCoordinates;
}
- bool sameAsTyped(const unsigned short *word, int length) const {
- if (length != mInputLength) {
- return false;
- }
- const int *inputCodes = mInputCodes;
- while (length--) {
- if ((unsigned int) *inputCodes != (unsigned int) *word) {
- return false;
- }
- inputCodes += MAX_PROXIMITY_CHARS_SIZE_INTERNAL;
- word++;
- }
- return true;
- }
-
// const
const ProximityInfo *mProximityInfo;
bool mHasTouchPositionCorrectionData;
diff --git a/native/jni/src/terminal_attributes.h b/native/jni/src/terminal_attributes.h
index d63364514..1ae9c7cbb 100644
--- a/native/jni/src/terminal_attributes.h
+++ b/native/jni/src/terminal_attributes.h
@@ -46,7 +46,7 @@ class TerminalAttributes {
// Gets the shortcut target itself as a uint16_t string. For parameters and return value
// see BinaryFormat::getWordAtAddress.
// TODO: make the output an uint32_t* to handle the whole unicode range.
- inline int getNextShortcutTarget(const int maxDepth, uint16_t *outWord) {
+ inline int getNextShortcutTarget(const int maxDepth, uint16_t *outWord, int *outFreq) {
const int shortcutFlags = BinaryFormat::getFlagsAndForwardPointer(mDict, &mPos);
mHasNextShortcutTarget =
0 != (shortcutFlags & BinaryFormat::FLAG_ATTRIBUTE_HAS_NEXT);
@@ -56,6 +56,7 @@ class TerminalAttributes {
if (NOT_A_CHARACTER == charCode) break;
outWord[i] = (uint16_t)charCode;
}
+ *outFreq = BinaryFormat::getAttributeFrequencyFromFlags(shortcutFlags);
mPos += BinaryFormat::CHARACTER_ARRAY_TERMINATOR_SIZE;
return i;
}
diff --git a/native/jni/src/unigram_dictionary.cpp b/native/jni/src/unigram_dictionary.cpp
index b6b0210cc..cc6d39a29 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,12 @@ 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);
+ if (0 != finalProbability) {
+ // If the probability is 0, we don't want to add this word. However we still
+ // want to add its shortcuts (including a possible whitelist entry) if any.
+ 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.
@@ -406,10 +411,21 @@ inline void UnigramDictionary::onTerminal(const int probability,
// with the same score. For the moment we use -1 to make sure the shortcut will
// never be in front of the word.
uint16_t shortcutTarget[MAX_WORD_LENGTH_INTERNAL];
+ int shortcutFrequency;
const int shortcutTargetStringLength = iterator.getNextShortcutTarget(
- MAX_WORD_LENGTH_INTERNAL, shortcutTarget);
- addWord(shortcutTarget, shortcutTargetStringLength, shortcutProbability,
- masterQueue);
+ MAX_WORD_LENGTH_INTERNAL, shortcutTarget, &shortcutFrequency);
+ int shortcutScore;
+ int kind;
+ if (shortcutFrequency == BinaryFormat::WHITELIST_SHORTCUT_FREQUENCY
+ && correction->sameAsTyped()) {
+ shortcutScore = S_INT_MAX;
+ kind = Dictionary::KIND_WHITELIST;
+ } else {
+ shortcutScore = shortcutProbability;
+ kind = Dictionary::KIND_CORRECTION;
+ }
+ addWord(shortcutTarget, shortcutTargetStringLength, shortcutScore,
+ masterQueue, kind);
}
}
}
@@ -424,7 +440,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 +588,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..1e4e00a23 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()));
@@ -127,7 +129,7 @@ class WordsPriorityQueue {
}
}
if (maxIndex > 0 && nsMaxSw) {
- memmove(&swBuffer[1], &swBuffer[0], maxIndex * sizeof(SuggestedWord*));
+ memmove(&swBuffer[1], &swBuffer[0], maxIndex * sizeof(SuggestedWord *));
swBuffer[0] = nsMaxSw;
}
}
@@ -138,11 +140,12 @@ class WordsPriorityQueue {
continue;
}
const unsigned int wordLength = sw->mWordLength;
- char *targetAdr = (char*) outputChars + i * MAX_WORD_LENGTH * sizeof(short);
+ unsigned short *targetAddress = outputChars + i * MAX_WORD_LENGTH;
frequencies[i] = sw->mScore;
- memcpy(targetAdr, sw->mWord, (wordLength) * sizeof(short));
+ outputTypes[i] = sw->mType;
+ memcpy(targetAddress, sw->mWord, wordLength * sizeof(unsigned short));
if (wordLength < MAX_WORD_LENGTH) {
- ((unsigned short*) targetAdr)[wordLength] = 0;
+ targetAddress[wordLength] = 0;
}
sw->mUsed = false;
}
@@ -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];
}
}
@@ -219,7 +222,7 @@ class WordsPriorityQueue {
before, beforeLength, word, wordLength, score);
}
- typedef std::priority_queue<SuggestedWord*, std::vector<SuggestedWord*>,
+ typedef std::priority_queue<SuggestedWord *, std::vector<SuggestedWord *>,
wordComparator> Suggestions;
Suggestions mSuggestions;
const unsigned int MAX_WORDS;