diff options
Diffstat (limited to 'native/jni/src/proximity_info.cpp')
-rw-r--r-- | native/jni/src/proximity_info.cpp | 152 |
1 files changed, 111 insertions, 41 deletions
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 |