diff options
-rw-r--r-- | java/src/com/android/inputmethod/keyboard/Keyboard.java | 1 | ||||
-rw-r--r-- | java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java | 39 | ||||
-rw-r--r-- | java/src/com/android/inputmethod/keyboard/ProximityInfo.java | 21 | ||||
-rw-r--r-- | java/src/com/android/inputmethod/latin/DebugSettings.java | 5 | ||||
-rw-r--r-- | native/jni/com_android_inputmethod_keyboard_ProximityInfo.cpp | 7 | ||||
-rw-r--r-- | native/src/proximity_info.cpp | 43 | ||||
-rw-r--r-- | native/src/proximity_info.h | 8 | ||||
-rw-r--r-- | native/src/unigram_dictionary.cpp | 24 | ||||
-rw-r--r-- | native/src/unigram_dictionary.h | 1 |
9 files changed, 95 insertions, 54 deletions
diff --git a/java/src/com/android/inputmethod/keyboard/Keyboard.java b/java/src/com/android/inputmethod/keyboard/Keyboard.java index 5660d1942..320b1bea2 100644 --- a/java/src/com/android/inputmethod/keyboard/Keyboard.java +++ b/java/src/com/android/inputmethod/keyboard/Keyboard.java @@ -388,6 +388,7 @@ public class Keyboard { } } + // TODO: Move this method to KeyboardSwitcher. public static String toThemeName(int themeId) { // This should be aligned with theme-*.xml resource files' themeId attribute. switch (themeId) { diff --git a/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java b/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java index ac8dd1b95..efe5aa9cf 100644 --- a/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java +++ b/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java @@ -39,8 +39,7 @@ import com.android.inputmethod.latin.SettingsValues; import com.android.inputmethod.latin.SubtypeSwitcher; import com.android.inputmethod.latin.Utils; -public class KeyboardSwitcher implements KeyboardState.SwitchActions, - SharedPreferences.OnSharedPreferenceChangeListener { +public class KeyboardSwitcher implements KeyboardState.SwitchActions { private static final String TAG = KeyboardSwitcher.class.getSimpleName(); public static final String PREF_KEYBOARD_LAYOUT = "pref_keyboard_layout_20110916"; @@ -94,7 +93,6 @@ public class KeyboardSwitcher implements KeyboardState.SwitchActions, mSubtypeSwitcher = SubtypeSwitcher.getInstance(); mState = new KeyboardState(this); setContextThemeWrapper(ims, getKeyboardThemeIndex(ims, prefs)); - prefs.registerOnSharedPreferenceChangeListener(this); mForceNonDistinctMultitouch = prefs.getBoolean( DebugSettings.FORCE_NON_DISTINCT_MULTITOUCH_KEY, false); } @@ -341,34 +339,26 @@ public class KeyboardSwitcher implements KeyboardState.SwitchActions, } public View onCreateInputView() { - return createInputView(mThemeIndex, true); - } - - private View createInputView(final int newThemeIndex, final boolean forceRecreate) { - if (mCurrentInputView != null && mThemeIndex == newThemeIndex && !forceRecreate) - return mCurrentInputView; - if (mKeyboardView != null) { mKeyboardView.closing(); } - final int oldThemeIndex = mThemeIndex; Utils.GCUtils.getInstance().reset(); boolean tryGC = true; for (int i = 0; i < Utils.GCUtils.GC_TRY_LOOP_MAX && tryGC; ++i) { try { - setContextThemeWrapper(mInputMethodService, newThemeIndex); + setContextThemeWrapper(mInputMethodService, mThemeIndex); mCurrentInputView = (InputView)LayoutInflater.from(mThemeContext).inflate( R.layout.input_view, null); tryGC = false; } catch (OutOfMemoryError e) { Log.w(TAG, "load keyboard failed: " + e); tryGC = Utils.GCUtils.getInstance().tryGCOrWait( - oldThemeIndex + "," + newThemeIndex, e); + Keyboard.toThemeName(mThemeIndex), e); } catch (InflateException e) { Log.w(TAG, "load keyboard failed: " + e); tryGC = Utils.GCUtils.getInstance().tryGCOrWait( - oldThemeIndex + "," + newThemeIndex, e); + Keyboard.toThemeName(mThemeIndex), e); } } @@ -385,27 +375,6 @@ public class KeyboardSwitcher implements KeyboardState.SwitchActions, return mCurrentInputView; } - private void postSetInputView(final View newInputView) { - final LatinIME latinIme = mInputMethodService; - latinIme.mHandler.post(new Runnable() { - @Override - public void run() { - if (newInputView != null) { - latinIme.setInputView(newInputView); - } - latinIme.updateInputViewShown(); - } - }); - } - - @Override - public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) { - if (PREF_KEYBOARD_LAYOUT.equals(key)) { - final int themeIndex = getKeyboardThemeIndex(mInputMethodService, sharedPreferences); - postSetInputView(createInputView(themeIndex, false)); - } - } - public void onNetworkStateChanged() { if (mKeyboardView != null) { mKeyboardView.updateShortcutKey(SubtypeSwitcher.getInstance().isShortcutImeReady()); diff --git a/java/src/com/android/inputmethod/keyboard/ProximityInfo.java b/java/src/com/android/inputmethod/keyboard/ProximityInfo.java index f96f71e8a..721ea135f 100644 --- a/java/src/com/android/inputmethod/keyboard/ProximityInfo.java +++ b/java/src/com/android/inputmethod/keyboard/ProximityInfo.java @@ -44,10 +44,11 @@ public class ProximityInfo { // TODO: Find a proper name for mKeyboardMinWidth private final int mKeyboardMinWidth; private final int mKeyboardHeight; + private final int mMostCommonKeyWidth; private final Key[][] mGridNeighbors; - ProximityInfo(int gridWidth, int gridHeight, int minWidth, int height, int keyWidth, - int keyHeight, Set<Key> keys, TouchPositionCorrection touchPositionCorrection, + ProximityInfo(int gridWidth, int gridHeight, int minWidth, int height, int mostCommonKeyWidth, + int mostCommonKeyHeight, Set<Key> keys, TouchPositionCorrection touchPositionCorrection, Map<Integer, List<Integer>> additionalProximityChars) { mGridWidth = gridWidth; mGridHeight = gridHeight; @@ -56,13 +57,15 @@ public class ProximityInfo { mCellHeight = (height + mGridHeight - 1) / mGridHeight; mKeyboardMinWidth = minWidth; mKeyboardHeight = height; - mKeyHeight = keyHeight; + mKeyHeight = mostCommonKeyHeight; + mMostCommonKeyWidth = mostCommonKeyWidth; mGridNeighbors = new Key[mGridSize][]; if (minWidth == 0 || height == 0) { // No proximity required. Keyboard might be more keys keyboard. return; } - computeNearestNeighbors(keyWidth, keys, touchPositionCorrection, additionalProximityChars); + computeNearestNeighbors( + mostCommonKeyWidth, keys, touchPositionCorrection, additionalProximityChars); } public static ProximityInfo createDummyProximityInfo() { @@ -74,8 +77,8 @@ public class ProximityInfo { final ProximityInfo spellCheckerProximityInfo = createDummyProximityInfo(); spellCheckerProximityInfo.mNativeProximityInfo = spellCheckerProximityInfo.setProximityInfoNative( - SpellCheckerProximityInfo.ROW_SIZE, 480, 300, 11, 3, proximity, 0, - null, null, null, null, null, null, null, null); + SpellCheckerProximityInfo.ROW_SIZE, 480, 300, 11, 3, (480 / 10), proximity, + 0, null, null, null, null, null, null, null, null); return spellCheckerProximityInfo; } @@ -85,7 +88,8 @@ public class ProximityInfo { } private native long setProximityInfoNative(int maxProximityCharsSize, int displayWidth, - int displayHeight, int gridWidth, int gridHeight, int[] proximityCharsArray, + int displayHeight, int gridWidth, int gridHeight, + int mostCommonKeyWidth, int[] proximityCharsArray, int keyCount, int[] keyXCoordinates, int[] keyYCoordinates, int[] keyWidths, int[] keyHeights, int[] keyCharCodes, float[] sweetSpotCenterX, float[] sweetSpotCenterY, float[] sweetSpotRadii); @@ -151,7 +155,8 @@ public class ProximityInfo { } mNativeProximityInfo = setProximityInfoNative(MAX_PROXIMITY_CHARS_SIZE, - keyboardWidth, keyboardHeight, mGridWidth, mGridHeight, proximityCharsArray, + keyboardWidth, keyboardHeight, mGridWidth, mGridHeight, mMostCommonKeyWidth, + proximityCharsArray, keyCount, keyXCoordinates, keyYCoordinates, keyWidths, keyHeights, keyCharCodes, sweetSpotCenterXs, sweetSpotCenterYs, sweetSpotRadii); } diff --git a/java/src/com/android/inputmethod/latin/DebugSettings.java b/java/src/com/android/inputmethod/latin/DebugSettings.java index 3805da154..870b33f9a 100644 --- a/java/src/com/android/inputmethod/latin/DebugSettings.java +++ b/java/src/com/android/inputmethod/latin/DebugSettings.java @@ -25,6 +25,8 @@ import android.preference.CheckBoxPreference; import android.preference.PreferenceActivity; import android.util.Log; +import com.android.inputmethod.keyboard.KeyboardSwitcher; + public class DebugSettings extends PreferenceActivity implements SharedPreferences.OnSharedPreferenceChangeListener { @@ -61,7 +63,8 @@ public class DebugSettings extends PreferenceActivity updateDebugMode(); mServiceNeedsRestart = true; } - } else if (key.equals(FORCE_NON_DISTINCT_MULTITOUCH_KEY)) { + } else if (key.equals(FORCE_NON_DISTINCT_MULTITOUCH_KEY) + || key.equals(KeyboardSwitcher.PREF_KEYBOARD_LAYOUT)) { mServiceNeedsRestart = true; } } diff --git a/native/jni/com_android_inputmethod_keyboard_ProximityInfo.cpp b/native/jni/com_android_inputmethod_keyboard_ProximityInfo.cpp index 6e4fefd72..844b23054 100644 --- a/native/jni/com_android_inputmethod_keyboard_ProximityInfo.cpp +++ b/native/jni/com_android_inputmethod_keyboard_ProximityInfo.cpp @@ -30,7 +30,7 @@ namespace latinime { static jlong latinime_Keyboard_setProximityInfo(JNIEnv *env, jobject object, jint maxProximityCharsSize, jint displayWidth, jint displayHeight, jint gridWidth, - jint gridHeight, jintArray proximityCharsArray, jint keyCount, + jint gridHeight, jint mostCommonkeyWidth, jintArray proximityCharsArray, jint keyCount, jintArray keyXCoordinateArray, jintArray keyYCoordinateArray, jintArray keyWidthArray, jintArray keyHeightArray, jintArray keyCharCodeArray, jfloatArray sweetSpotCenterXArray, jfloatArray sweetSpotCenterYArray, @@ -45,7 +45,8 @@ static jlong latinime_Keyboard_setProximityInfo(JNIEnv *env, jobject object, jfloat *sweetSpotCenterYs = safeGetFloatArrayElements(env, sweetSpotCenterYArray); jfloat *sweetSpotRadii = safeGetFloatArrayElements(env, sweetSpotRadiusArray); ProximityInfo *proximityInfo = new ProximityInfo(maxProximityCharsSize, displayWidth, - displayHeight, gridWidth, gridHeight, (const uint32_t*)proximityChars, + displayHeight, gridWidth, gridHeight, mostCommonkeyWidth, + (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, (const float*)sweetSpotCenterXs, (const float*)sweetSpotCenterYs, @@ -69,7 +70,7 @@ static void latinime_Keyboard_release(JNIEnv *env, jobject object, jlong proximi } static JNINativeMethod sKeyboardMethods[] = { - {"setProximityInfoNative", "(IIIII[II[I[I[I[I[I[F[F[F)J", + {"setProximityInfoNative", "(IIIIII[II[I[I[I[I[I[F[F[F)J", (void*)latinime_Keyboard_setProximityInfo}, {"releaseProximityInfoNative", "(J)V", (void*)latinime_Keyboard_release} }; diff --git a/native/src/proximity_info.cpp b/native/src/proximity_info.cpp index b6bab2274..ad19f58b5 100644 --- a/native/src/proximity_info.cpp +++ b/native/src/proximity_info.cpp @@ -35,12 +35,14 @@ inline void copyOrFillZero(void *to, const void *from, size_t size) { ProximityInfo::ProximityInfo(const int maxProximityCharsSize, const int keyboardWidth, const int keyboardHeight, const int gridWidth, const int gridHeight, + const int mostCommonKeyWidth, 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, 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), + 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)), @@ -123,6 +125,47 @@ bool ProximityInfo::hasSpaceProximity(const int x, const int y) const { return false; } +bool ProximityInfo::isOnKey(const int keyId, const int x, const int y) { + const int left = mKeyXCoordinates[keyId]; + const int top = mKeyYCoordinates[keyId]; + const int right = left + mKeyWidths[keyId] + 1; + const int bottom = top + mKeyHeights[keyId]; + return left < right && top < bottom && x >= left && x < right && y >= top && y < bottom; +} + +int ProximityInfo::squaredDistanceToEdge(const int keyId, const int x, const int y) { + const int left = mKeyXCoordinates[keyId]; + const int top = mKeyYCoordinates[keyId]; + const int right = left + mKeyWidths[keyId] + 1; + const int bottom = top + mKeyHeights[keyId]; + const int edgeX = x < left ? left : (x > right ? right : x); + const int edgeY = y < top ? top : (y > bottom ? bottom : y); + const int dx = x - edgeX; + const int dy = y - edgeY; + return dx * dx + dy * dy; +} + +void ProximityInfo::calculateNearbyKeyCodes( + const int x, const int y, const uint32_t primaryKey, int *inputCodes) { + int insertPos = 0; + inputCodes[insertPos++] = primaryKey; + const int startIndex = getStartIndexFromCoordinates(x, y); + for (int i = 0; i < MAX_PROXIMITY_CHARS_SIZE; ++i) { + const uint32_t c = mProximityCharsArray[startIndex + i]; + if (c < KEYCODE_SPACE || c == primaryKey) { + continue; + } + for (int j = 0; j < KEY_COUNT; ++j) { + const bool onKey = isOnKey(j, x, y); + const int distance = squaredDistanceToEdge(j, x, y); + if (onKey || distance < MOST_COMMON_KEY_WIDTH_SQUARE) { + inputCodes[insertPos++] = c; + } + } + } + // TODO: calculate additional chars +} + // TODO: Calculate nearby codes here. void ProximityInfo::setInputParams(const int* inputCodes, const int inputLength, const int* xCoordinates, const int* yCoordinates) { diff --git a/native/src/proximity_info.h b/native/src/proximity_info.h index b77c1bb0a..caabadfb6 100644 --- a/native/src/proximity_info.h +++ b/native/src/proximity_info.h @@ -45,13 +45,14 @@ class ProximityInfo { ProximityInfo(const int maxProximityCharsSize, const int keyboardWidth, const int keybaordHeight, const int gridWidth, const int gridHeight, + const int mostCommonkeyWidth, 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, 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, + void setInputParams(const int *inputCodes, const int inputLength, const int *xCoordinates, const int *yCoordinates); const int* getProximityCharsAt(const int index) const; unsigned short getPrimaryCharAt(const int index) const; @@ -87,12 +88,17 @@ class ProximityInfo { // the radius of the key is assigned to zero. return mSweetSpotRadii[keyIndex] > 0.0; } + bool isOnKey(const int keyId, const int x, const int y); + int squaredDistanceToEdge(const int keyId, const int x, const int y); + void calculateNearbyKeyCodes( + const int x, const int y, const uint32_t primaryKey, int *inputCodes); const int MAX_PROXIMITY_CHARS_SIZE; const int KEYBOARD_WIDTH; const int KEYBOARD_HEIGHT; const int GRID_WIDTH; const int GRID_HEIGHT; + const int MOST_COMMON_KEY_WIDTH_SQUARE; const int CELL_WIDTH; const int CELL_HEIGHT; const int KEY_COUNT; diff --git a/native/src/unigram_dictionary.cpp b/native/src/unigram_dictionary.cpp index 0b646d1cd..10aa7e296 100644 --- a/native/src/unigram_dictionary.cpp +++ b/native/src/unigram_dictionary.cpp @@ -91,12 +91,16 @@ bool UnigramDictionary::isDigraph(const int *codes, const int i, const int codes // codesRemain is the remaining size in codesSrc. void UnigramDictionary::getWordWithDigraphSuggestionsRec(ProximityInfo *proximityInfo, const int *xcoordinates, const int *ycoordinates, const int *codesBuffer, + int *xCoordinatesBuffer, int *yCoordinatesBuffer, const int codesBufferSize, const int flags, const int *codesSrc, const int codesRemain, const int currentDepth, int *codesDest, Correction *correction, WordsPriorityQueuePool *queuePool) { + const int startIndex = (codesDest - codesBuffer) / MAX_PROXIMITY_CHARS; if (currentDepth < MAX_UMLAUT_SEARCH_DEPTH) { for (int i = 0; i < codesRemain; ++i) { + xCoordinatesBuffer[startIndex + i] = xcoordinates[codesBufferSize - codesRemain + i]; + yCoordinatesBuffer[startIndex + i] = ycoordinates[codesBufferSize - codesRemain + i]; if (isDigraph(codesSrc, i, codesRemain)) { // Found a digraph. We will try both spellings. eg. the word is "pruefen" @@ -108,7 +112,7 @@ void UnigramDictionary::getWordWithDigraphSuggestionsRec(ProximityInfo *proximit ++i; memcpy(codesDest, codesSrc, i * BYTES_IN_ONE_CHAR); getWordWithDigraphSuggestionsRec(proximityInfo, xcoordinates, ycoordinates, - codesBuffer, codesBufferSize, flags, + codesBuffer, xCoordinatesBuffer, yCoordinatesBuffer, codesBufferSize, flags, codesSrc + (i + 1) * MAX_PROXIMITY_CHARS, codesRemain - i - 1, currentDepth + 1, codesDest + i * MAX_PROXIMITY_CHARS, correction, queuePool); @@ -119,7 +123,7 @@ void UnigramDictionary::getWordWithDigraphSuggestionsRec(ProximityInfo *proximit memcpy(codesDest + i * MAX_PROXIMITY_CHARS, codesSrc + i * MAX_PROXIMITY_CHARS, BYTES_IN_ONE_CHAR); getWordWithDigraphSuggestionsRec(proximityInfo, xcoordinates, ycoordinates, - codesBuffer, codesBufferSize, flags, + codesBuffer, xCoordinatesBuffer, yCoordinatesBuffer, codesBufferSize, flags, codesSrc + i * MAX_PROXIMITY_CHARS, codesRemain - i, currentDepth + 1, codesDest + i * MAX_PROXIMITY_CHARS, correction, queuePool); return; @@ -133,11 +137,16 @@ void UnigramDictionary::getWordWithDigraphSuggestionsRec(ProximityInfo *proximit // eg. if the word is "ueberpruefen" we'll test, in order, against // "uberprufen", "uberpruefen", "ueberprufen", "ueberpruefen". const unsigned int remainingBytes = BYTES_IN_ONE_CHAR * codesRemain; - if (0 != remainingBytes) + if (0 != remainingBytes) { memcpy(codesDest, codesSrc, remainingBytes); + memcpy(&xCoordinatesBuffer[startIndex], &xcoordinates[codesBufferSize - codesRemain], + sizeof(int) * codesRemain); + memcpy(&yCoordinatesBuffer[startIndex], &ycoordinates[codesBufferSize - codesRemain], + sizeof(int) * codesRemain); + } - getWordSuggestions(proximityInfo, xcoordinates, ycoordinates, codesBuffer, - (codesDest - codesBuffer) / MAX_PROXIMITY_CHARS + codesRemain, flags, correction, + getWordSuggestions(proximityInfo, xCoordinatesBuffer, yCoordinatesBuffer, codesBuffer, + startIndex + codesRemain, flags, correction, queuePool); } @@ -146,11 +155,15 @@ int UnigramDictionary::getSuggestions(ProximityInfo *proximityInfo, const int *ycoordinates, const int *codes, const int codesSize, const int flags, unsigned short *outWords, int *frequencies) { + queuePool->clearAll(); Correction* masterCorrection = correction; if (REQUIRES_GERMAN_UMLAUT_PROCESSING & flags) { // Incrementally tune the word and try all possibilities int codesBuffer[getCodesBufferSize(codes, codesSize, MAX_PROXIMITY_CHARS)]; + int xCoordinatesBuffer[codesSize]; + int yCoordinatesBuffer[codesSize]; getWordWithDigraphSuggestionsRec(proximityInfo, xcoordinates, ycoordinates, codesBuffer, + xCoordinatesBuffer, yCoordinatesBuffer, codesSize, flags, codes, codesSize, 0, codesBuffer, masterCorrection, queuePool); } else { // Normal processing getWordSuggestions(proximityInfo, xcoordinates, ycoordinates, codes, codesSize, flags, @@ -192,7 +205,6 @@ void UnigramDictionary::getWordSuggestions(ProximityInfo *proximityInfo, PROF_OPEN; PROF_START(0); - queuePool->clearAll(); PROF_END(0); PROF_START(1); diff --git a/native/src/unigram_dictionary.h b/native/src/unigram_dictionary.h index 396a81149..12b68d71b 100644 --- a/native/src/unigram_dictionary.h +++ b/native/src/unigram_dictionary.h @@ -89,6 +89,7 @@ class UnigramDictionary { bool isDigraph(const int *codes, const int i, const int codesSize) const; void getWordWithDigraphSuggestionsRec(ProximityInfo *proximityInfo, const int *xcoordinates, const int* ycoordinates, const int *codesBuffer, + int *xCoordinatesBuffer, int *yCoordinatesBuffer, const int codesBufferSize, const int flags, const int* codesSrc, const int codesRemain, const int currentDepth, int* codesDest, Correction *correction, WordsPriorityQueuePool* queuePool); |