From ad35835baccb4101c3d8766fadbf4d127e41b6cb Mon Sep 17 00:00:00 2001 From: Yusuke Nojima Date: Thu, 29 Sep 2011 16:44:54 +0900 Subject: [PATCH] Pass the touch position correction data to native. Change-Id: I92958779377a530410d1682100f9d0a2ba267dea --- CleanSpec.mk | 1 + .../inputmethod/keyboard/Keyboard.java | 2 +- .../inputmethod/keyboard/ProximityInfo.java | 71 +++++++++++++++---- ...oid_inputmethod_keyboard_ProximityInfo.cpp | 16 ++++- native/jni/jni_common.h | 14 ++++ .../src/defines_touch_position_correction.h | 61 ---------------- native/src/proximity_info.cpp | 33 ++++----- native/src/proximity_info.h | 15 ++-- 8 files changed, 107 insertions(+), 106 deletions(-) delete mode 100644 native/src/defines_touch_position_correction.h diff --git a/CleanSpec.mk b/CleanSpec.mk index 505e41b49..c274a6c44 100644 --- a/CleanSpec.mk +++ b/CleanSpec.mk @@ -50,6 +50,7 @@ $(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/app/LatinIME.apk) $(call add-clean-step, rm -rf $(PRODUCT_OUT)/obj/SHARED_LIBRARIES/libjni_latinime_intermediates) $(call add-clean-step, rm -rf $(PRODUCT_OUT)/obj/SHARED_LIBRARIES/libjni_latinime_intermediates) $(call add-clean-step, rm -rf $(PRODUCT_OUT)/obj/SHARED_LIBRARIES/libjni_latinime_intermediates) +$(call add-clean-step, rm -rf $(PRODUCT_OUT)/obj/SHARED_LIBRARIES/libjni_latinime_intermediates) # ************************************************ # NEWER CLEAN STEPS MUST BE AT THE END OF THE LIST # ************************************************ diff --git a/java/src/com/android/inputmethod/keyboard/Keyboard.java b/java/src/com/android/inputmethod/keyboard/Keyboard.java index f77155ee3..9e4c1ea79 100644 --- a/java/src/com/android/inputmethod/keyboard/Keyboard.java +++ b/java/src/com/android/inputmethod/keyboard/Keyboard.java @@ -138,7 +138,7 @@ public class Keyboard { mProximityInfo = new ProximityInfo( params.GRID_WIDTH, params.GRID_HEIGHT, mOccupiedWidth, mOccupiedHeight, - mMostCommonKeyWidth, mKeys, params.mTouchPositionCorrectionXs, + mMostCommonKeyWidth, mMostCommonKeyHeight, mKeys, params.mTouchPositionCorrectionXs, params.mTouchPositionCorrectionYs, params.mTouchPositionCorrectionRadii); } diff --git a/java/src/com/android/inputmethod/keyboard/ProximityInfo.java b/java/src/com/android/inputmethod/keyboard/ProximityInfo.java index 210ab48a1..d35b1a939 100644 --- a/java/src/com/android/inputmethod/keyboard/ProximityInfo.java +++ b/java/src/com/android/inputmethod/keyboard/ProximityInfo.java @@ -16,6 +16,9 @@ package com.android.inputmethod.keyboard; +import android.graphics.Rect; + +import com.android.inputmethod.keyboard.Key; import com.android.inputmethod.latin.Utils; import com.android.inputmethod.latin.spellcheck.SpellCheckerProximityInfo; @@ -27,9 +30,9 @@ public class ProximityInfo { public static final int MAX_PROXIMITY_CHARS_SIZE = 16; /** Number of key widths from current touch point to search for nearest keys. */ private static float SEARCH_DISTANCE = 1.2f; - private static final int UNKNOWN_THEME = -1; private static final int[] EMPTY_INT_ARRAY = new int[0]; + private final int mKeyHeight; private final int mGridWidth; private final int mGridHeight; private final int mGridSize; @@ -45,8 +48,8 @@ public class ProximityInfo { private final float[] mTouchPositionCorrectionRadii; ProximityInfo(int gridWidth, int gridHeight, int minWidth, int height, int keyWidth, - List keys, float[] touchPositionCorrectionXs, float[] touchPositionCorrectionYs, - float[] touchPositionCorrectionRadii) { + int keyHeight, List keys, float[] touchPositionCorrectionXs, + float[] touchPositionCorrectionYs, float[] touchPositionCorrectionRadii) { mGridWidth = gridWidth; mGridHeight = gridHeight; mGridSize = mGridWidth * mGridHeight; @@ -54,6 +57,7 @@ public class ProximityInfo { mCellHeight = (height + mGridHeight - 1) / mGridHeight; mKeyboardMinWidth = minWidth; mKeyboardHeight = height; + mKeyHeight = keyHeight; mTouchPositionCorrectionXs = touchPositionCorrectionXs; mTouchPositionCorrectionYs = touchPositionCorrectionYs; mTouchPositionCorrectionRadii = touchPositionCorrectionRadii; @@ -66,7 +70,7 @@ public class ProximityInfo { } public static ProximityInfo createDummyProximityInfo() { - return new ProximityInfo(1, 1, 1, 1, 1, Collections.emptyList(), null, null, null); + return new ProximityInfo(1, 1, 1, 1, 1, 1, Collections.emptyList(), null, null, null); } public static ProximityInfo createSpellCheckerProximityInfo() { @@ -75,7 +79,7 @@ public class ProximityInfo { spellCheckerProximityInfo.setProximityInfoNative( SpellCheckerProximityInfo.ROW_SIZE, 480, 300, 10, 3, SpellCheckerProximityInfo.PROXIMITY, - 0, null, null, null, null, null, UNKNOWN_THEME); + 0, null, null, null, null, null, null, null, null); return spellCheckerProximityInfo; } @@ -86,7 +90,8 @@ public class ProximityInfo { private native int setProximityInfoNative(int maxProximityCharsSize, int displayWidth, int displayHeight, int gridWidth, int gridHeight, int[] proximityCharsArray, int keyCount, int[] keyXCoordinates, int[] keyYCoordinates, - int[] keyWidths, int[] keyHeights, int[] keyCharCodes, int themeId); + int[] keyWidths, int[] keyHeights, int[] keyCharCodes, + float[] sweetSpotCenterX, float[] sweetSpotCenterY, float[] sweetSpotRadii); private native void releaseProximityInfoNative(int nativeProximityInfo); private final void setProximityInfo(int[][] gridNeighborKeyIndexes, int keyboardWidth, @@ -101,12 +106,11 @@ public class ProximityInfo { } } final int keyCount = keys.size(); - int[] keyXCoordinates = new int[keyCount]; - int[] keyYCoordinates = new int[keyCount]; - int[] keyWidths = new int[keyCount]; - int[] keyHeights = new int[keyCount]; - int[] keyCharCodes = new int[keyCount]; - final int themeId = 5; // TODO: Use real theme id. + final int[] keyXCoordinates = new int[keyCount]; + final int[] keyYCoordinates = new int[keyCount]; + final int[] keyWidths = new int[keyCount]; + final int[] keyHeights = new int[keyCount]; + final int[] keyCharCodes = new int[keyCount]; for (int i = 0; i < keyCount; ++i) { final Key key = keys.get(i); keyXCoordinates[i] = key.mX; @@ -115,10 +119,51 @@ public class ProximityInfo { keyHeights[i] = key.mHeight; keyCharCodes[i] = key.mCode; } + + final boolean hasTouchPositionCorrectionData = + mTouchPositionCorrectionXs != null + && mTouchPositionCorrectionYs != null + && mTouchPositionCorrectionRadii != null + && mTouchPositionCorrectionXs.length > 0 + && mTouchPositionCorrectionYs.length > 0 + && mTouchPositionCorrectionRadii.length > 0; + final float[] sweetSpotCenterXs = + hasTouchPositionCorrectionData ? new float[keyCount] : null; + final float[] sweetSpotCenterYs = + hasTouchPositionCorrectionData ? new float[keyCount] : null; + final float[] sweetSpotRadii = + hasTouchPositionCorrectionData ? new float[keyCount] : null; + if (hasTouchPositionCorrectionData) { + calculateSweetSpot(keys, sweetSpotCenterXs, sweetSpotCenterYs, sweetSpotRadii); + } + mNativeProximityInfo = setProximityInfoNative(MAX_PROXIMITY_CHARS_SIZE, keyboardWidth, keyboardHeight, mGridWidth, mGridHeight, proximityCharsArray, keyCount, keyXCoordinates, keyYCoordinates, keyWidths, keyHeights, keyCharCodes, - themeId); + sweetSpotCenterXs, sweetSpotCenterYs, sweetSpotRadii); + } + + private void calculateSweetSpot(List keys, float[] sweetSpotCenterXs, + float[] sweetSpotCenterYs, float[] sweetSpotRadii) { + final int keyCount = keys.size(); + for (int i = 0; i < keyCount; ++i) { + final Key key = keys.get(i); + final Rect hitBox = key.mHitBox; + final int row = hitBox.top / mKeyHeight; + if (row < mTouchPositionCorrectionRadii.length) { + final float hitBoxCenterX = (hitBox.left + hitBox.right) * 0.5f; + final float hitBoxCenterY = (hitBox.top + hitBox.bottom) * 0.5f; + final float hitBoxWidth = hitBox.right - hitBox.left; + final float hitBoxHeight = hitBox.bottom - hitBox.top; + final float x = mTouchPositionCorrectionXs[row]; + final float y = mTouchPositionCorrectionYs[row]; + final float radius = mTouchPositionCorrectionRadii[row]; + sweetSpotCenterXs[i] = hitBoxCenterX + x * hitBoxWidth; + sweetSpotCenterYs[i] = hitBoxCenterY + y * hitBoxHeight; + sweetSpotRadii[i] = radius + * (float)Math.sqrt(hitBoxWidth * hitBoxWidth + hitBoxHeight * hitBoxHeight); + } + } } public int getNativeProximityInfo() { diff --git a/native/jni/com_android_inputmethod_keyboard_ProximityInfo.cpp b/native/jni/com_android_inputmethod_keyboard_ProximityInfo.cpp index 07cee4053..595ea2fdc 100644 --- a/native/jni/com_android_inputmethod_keyboard_ProximityInfo.cpp +++ b/native/jni/com_android_inputmethod_keyboard_ProximityInfo.cpp @@ -32,18 +32,27 @@ static jint latinime_Keyboard_setProximityInfo(JNIEnv *env, jobject object, jint maxProximityCharsSize, jint displayWidth, jint displayHeight, jint gridWidth, jint gridHeight, jintArray proximityCharsArray, jint keyCount, jintArray keyXCoordinateArray, jintArray keyYCoordinateArray, jintArray keyWidthArray, - jintArray keyHeightArray, jintArray keyCharCodeArray, jint themeId) { + jintArray keyHeightArray, jintArray keyCharCodeArray, + jfloatArray sweetSpotCenterXArray, jfloatArray sweetSpotCenterYArray, + jfloatArray sweetSpotRadiusArray) { jint *proximityChars = env->GetIntArrayElements(proximityCharsArray, NULL); 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(maxProximityCharsSize, displayWidth, displayHeight, gridWidth, gridHeight, (const uint32_t*)proximityChars, keyCount, (const int32_t*)keyXCoordinates, (const int32_t*)keyYCoordinates, (const int32_t*)keyWidths, (const int32_t*)keyHeights, (const int32_t*)keyCharCodes, - themeId); + (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); @@ -60,7 +69,8 @@ static void latinime_Keyboard_release(JNIEnv *env, jobject object, jint proximit } static JNINativeMethod sKeyboardMethods[] = { - {"setProximityInfoNative", "(IIIII[II[I[I[I[I[II)I", (void*)latinime_Keyboard_setProximityInfo}, + {"setProximityInfoNative", "(IIIII[II[I[I[I[I[I[F[F[F)I", + (void*)latinime_Keyboard_setProximityInfo}, {"releaseProximityInfoNative", "(I)V", (void*)latinime_Keyboard_release} }; diff --git a/native/jni/jni_common.h b/native/jni/jni_common.h index dbf6d3e19..9548e1b3f 100644 --- a/native/jni/jni_common.h +++ b/native/jni/jni_common.h @@ -35,12 +35,26 @@ inline jint *safeGetIntArrayElements(JNIEnv *env, jintArray jArray) { } } +inline jfloat *safeGetFloatArrayElements(JNIEnv *env, jfloatArray jArray) { + if (jArray) { + return env->GetFloatArrayElements(jArray, NULL); + } else { + return NULL; + } +} + 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/src/defines_touch_position_correction.h b/native/src/defines_touch_position_correction.h deleted file mode 100644 index 122906804..000000000 --- a/native/src/defines_touch_position_correction.h +++ /dev/null @@ -1,61 +0,0 @@ -/* -** -** Copyright 2011, 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_DEFINES_TOUCH_POSITION_CORRECTION_H -#define LATINIME_DEFINES_TOUCH_POSITION_CORRECTION_H - -#define OUTER_SWEET_SPOT_RADIUS_RATIO 1.3 - -static const char* TOUCH_POSITION_CORRECTION_GROUPS[] = { - "qwertyuiop", - "a", - "sdfghjk", - "l", - "zxcvbnm", -}; - -// (center X) / (key width) -static const float RELATIVE_TOUCH_CENTER_X[] = { - 0, // qwertyuiop - -0.26871, // a - 0, // sdfghjk - 0.028050, // l - 0, // zxcvbnm -}; - -// (center Y) / (key height) -static const float RELATIVE_TOUCH_CENTER_Y[] = { - 0.192088, // qwertyuiop - 0.214100, // a - 0.216640, // sdfghjk - 0.233288, // l - 0.286598, // zxcvbnm -}; - -// (sweet spot radius) / ((key width) + (key height)) -static const float SWEET_SPOT_RADIUS[] = { - 0.148955, // qwertyuiop - 0.185437, // a - 0.145522, // sdfghjk - 0.156882, // l - 0.144211, // zxcvbnm -}; - -#define CORRECTION_GROUP_COUNT \ - ((int)(sizeof(TOUCH_POSITION_CORRECTION_GROUPS) / sizeof(TOUCH_POSITION_CORRECTION_GROUPS[0]))) - -#endif // LATINIME_DEFINES_TOUCH_POSITION_CORRECTION_H diff --git a/native/src/proximity_info.cpp b/native/src/proximity_info.cpp index 58842b92f..4ff6e0ac0 100644 --- a/native/src/proximity_info.cpp +++ b/native/src/proximity_info.cpp @@ -20,7 +20,6 @@ #define LOG_TAG "LatinIME: proximity_info.cpp" -#include "defines_touch_position_correction.h" #include "dictionary.h" #include "proximity_info.h" @@ -38,12 +37,13 @@ ProximityInfo::ProximityInfo(const int maxProximityCharsSize, const int keyboard const int keyboardHeight, const int gridWidth, const int gridHeight, const uint32_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, int themeId) + const int32_t *keyCharCodes, const float *sweetSpotCenterXs, const float *sweetSpotCenterYs, + const float *sweetSpotRadii) : MAX_PROXIMITY_CHARS_SIZE(maxProximityCharsSize), KEYBOARD_WIDTH(keyboardWidth), KEYBOARD_HEIGHT(keyboardHeight), GRID_WIDTH(gridWidth), GRID_HEIGHT(gridHeight), CELL_WIDTH((keyboardWidth + gridWidth - 1) / gridWidth), CELL_HEIGHT((keyboardHeight + gridHeight - 1) / gridHeight), - KEY_COUNT(min(keyCount, MAX_KEY_COUNT_IN_A_KEYBOARD)), THEME_ID(themeId) { + KEY_COUNT(min(keyCount, MAX_KEY_COUNT_IN_A_KEYBOARD)) { const int len = GRID_WIDTH * GRID_HEIGHT * MAX_PROXIMITY_CHARS_SIZE; mProximityCharsArray = new uint32_t[len]; if (DEBUG_PROXIMITY_INFO) { @@ -56,33 +56,24 @@ ProximityInfo::ProximityInfo(const int maxProximityCharsSize, const int keyboard 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])); - initializeCodeToGroup(); initializeCodeToKeyIndex(); } -// Build the reversed look up table from the char code to the index in its group. -// see TOUCH_POSITION_CORRECTION_GROUPS -void ProximityInfo::initializeCodeToGroup() { - memset(mCodeToGroup, -1, (MAX_GROUPED_CHAR_CODE + 1) * sizeof(mCodeToGroup[0])); - for (int i = 0; i < CORRECTION_GROUP_COUNT; ++i) { - const char *group = TOUCH_POSITION_CORRECTION_GROUPS[i]; - for (int j = 0; group[j]; ++j) { - const int code = group[j]; - if (0 <= code && code <= MAX_GROUPED_CHAR_CODE) - mCodeToGroup[code] = i; - } - } -} - // Build the reversed look up table from the char code to the index in mKeyXCoordinates, // mKeyYCoordinates, mKeyWidths, mKeyHeights, mKeyCharCodes. void ProximityInfo::initializeCodeToKeyIndex() { - memset(mCodeToKeyIndex, -1, (MAX_GROUPED_CHAR_CODE + 1) * sizeof(mCodeToKeyIndex[0])); + memset(mCodeToKeyIndex, -1, (MAX_CHAR_CODE + 1) * sizeof(mCodeToKeyIndex[0])); for (int i = 0; i < KEY_COUNT; ++i) { const int code = mKeyCharCodes[i]; - if (0 <= code && code <= MAX_GROUPED_CHAR_CODE) + if (0 <= code && code <= MAX_CHAR_CODE) { mCodeToKeyIndex[code] = i; + } } } @@ -210,6 +201,6 @@ bool ProximityInfo::sameAsTyped(const unsigned short *word, int length) const { } const int ProximityInfo::MAX_KEY_COUNT_IN_A_KEYBOARD; -const int ProximityInfo::MAX_GROUPED_CHAR_CODE; +const int ProximityInfo::MAX_CHAR_CODE; } // namespace latinime diff --git a/native/src/proximity_info.h b/native/src/proximity_info.h index 3190e73ef..b1e8236d3 100644 --- a/native/src/proximity_info.h +++ b/native/src/proximity_info.h @@ -37,7 +37,8 @@ public: const int keybaordHeight, const int gridWidth, const int gridHeight, const uint32_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, int themeId); + const int32_t *keyCharCodes, const float *sweetSpotCenterXs, + const float *sweetSpotCenterYs, const float *sweetSpotRadii); ~ProximityInfo(); bool hasSpaceProximity(const int x, const int y) const; void setInputParams(const int* inputCodes, const int inputLength); @@ -55,11 +56,10 @@ public: private: // The max number of the keys in one keyboard layout static const int MAX_KEY_COUNT_IN_A_KEYBOARD = 64; - // The upper limit of the char code in TOUCH_POSITION_CORRECTION_GROUP - static const int MAX_GROUPED_CHAR_CODE = 127; + // The upper limit of the char code in mCodeToKeyIndex + static const int MAX_CHAR_CODE = 127; int getStartIndexFromCoordinates(const int x, const int y) const; - void initializeCodeToGroup(); void initializeCodeToKeyIndex(); const int MAX_PROXIMITY_CHARS_SIZE; const int KEYBOARD_WIDTH; @@ -69,7 +69,6 @@ private: const int CELL_WIDTH; const int CELL_HEIGHT; const int KEY_COUNT; - const int THEME_ID; const int *mInputCodes; uint32_t *mProximityCharsArray; int32_t mKeyXCoordinates[MAX_KEY_COUNT_IN_A_KEYBOARD]; @@ -77,10 +76,12 @@ private: int32_t mKeyWidths[MAX_KEY_COUNT_IN_A_KEYBOARD]; int32_t mKeyHeights[MAX_KEY_COUNT_IN_A_KEYBOARD]; int32_t mKeyCharCodes[MAX_KEY_COUNT_IN_A_KEYBOARD]; + float mSweetSpotCenterXs[MAX_KEY_COUNT_IN_A_KEYBOARD]; + float mSweetSpotCenterYs[MAX_KEY_COUNT_IN_A_KEYBOARD]; + float mSweetSpotRadii[MAX_KEY_COUNT_IN_A_KEYBOARD]; int mInputLength; unsigned short mPrimaryInputWord[MAX_WORD_LENGTH_INTERNAL]; - int mCodeToGroup[MAX_GROUPED_CHAR_CODE + 1]; - int mCodeToKeyIndex[MAX_GROUPED_CHAR_CODE + 1]; + int mCodeToKeyIndex[MAX_CHAR_CODE + 1]; }; } // namespace latinime