aboutsummaryrefslogtreecommitdiffstats
path: root/java/src
diff options
context:
space:
mode:
Diffstat (limited to 'java/src')
-rw-r--r--java/src/com/android/inputmethod/keyboard/KeyDetector.java41
-rw-r--r--java/src/com/android/inputmethod/keyboard/Keyboard.java36
-rw-r--r--java/src/com/android/inputmethod/keyboard/ProximityInfo.java50
-rw-r--r--java/src/com/android/inputmethod/latin/WordComposer.java4
4 files changed, 115 insertions, 16 deletions
diff --git a/java/src/com/android/inputmethod/keyboard/KeyDetector.java b/java/src/com/android/inputmethod/keyboard/KeyDetector.java
index 0d271625b..bff491ffd 100644
--- a/java/src/com/android/inputmethod/keyboard/KeyDetector.java
+++ b/java/src/com/android/inputmethod/keyboard/KeyDetector.java
@@ -19,12 +19,14 @@ package com.android.inputmethod.keyboard;
import android.util.Log;
import java.util.Arrays;
+import java.util.List;
public class KeyDetector {
private static final String TAG = KeyDetector.class.getSimpleName();
private static final boolean DEBUG = false;
public static final int NOT_A_CODE = -1;
+ private static final int ADDITIONAL_PROXIMITY_CHAR_DELIMITER_CODE = 2;
private final int mKeyHysteresisDistanceSquared;
@@ -154,8 +156,9 @@ public class KeyDetector {
return distances.length;
}
- private void getNearbyKeyCodes(final int[] allCodes) {
+ private void getNearbyKeyCodes(final int primaryCode, final int[] allCodes) {
final Key[] neighborKeys = mNeighborKeys;
+ final int maxCodesSize = allCodes.length;
// allCodes[0] should always have the key code even if it is a non-letter key.
if (neighborKeys[0] == null) {
@@ -164,7 +167,7 @@ public class KeyDetector {
}
int numCodes = 0;
- for (int j = 0; j < neighborKeys.length && numCodes < allCodes.length; j++) {
+ for (int j = 0; j < neighborKeys.length && numCodes < maxCodesSize; j++) {
final Key key = neighborKeys[j];
if (key == null)
break;
@@ -174,6 +177,38 @@ public class KeyDetector {
continue;
allCodes[numCodes++] = code;
}
+ if (maxCodesSize <= numCodes) {
+ return;
+ }
+ if (primaryCode != NOT_A_CODE) {
+ final List<Integer> additionalChars =
+ mKeyboard.getAdditionalProximityChars().get(primaryCode);
+ if (additionalChars == null || additionalChars.size() == 0) {
+ return;
+ }
+ int currentCodesSize = numCodes;
+ allCodes[numCodes++] = ADDITIONAL_PROXIMITY_CHAR_DELIMITER_CODE;
+ if (maxCodesSize <= numCodes) {
+ return;
+ }
+ // TODO: This is O(N^2). Assuming additionalChars.size() is up to 4 or 5.
+ for (int i = 0; i < additionalChars.size(); ++i) {
+ final int additionalChar = additionalChars.get(i);
+ boolean contains = false;
+ for (int j = 0; j < currentCodesSize; ++j) {
+ if (additionalChar == allCodes[j]) {
+ contains = true;
+ break;
+ }
+ }
+ if (!contains) {
+ allCodes[numCodes++] = additionalChar;
+ if (maxCodesSize <= numCodes) {
+ return;
+ }
+ }
+ }
+ }
}
/**
@@ -205,7 +240,7 @@ public class KeyDetector {
}
if (allCodes != null && allCodes.length > 0) {
- getNearbyKeyCodes(allCodes);
+ getNearbyKeyCodes(primaryKey != null ? primaryKey.mCode : NOT_A_CODE, allCodes);
if (DEBUG) {
Log.d(TAG, "x=" + x + " y=" + y
+ " primary=" + printableCode(primaryKey)
diff --git a/java/src/com/android/inputmethod/keyboard/Keyboard.java b/java/src/com/android/inputmethod/keyboard/Keyboard.java
index 6653dec4b..10e0a5b01 100644
--- a/java/src/com/android/inputmethod/keyboard/Keyboard.java
+++ b/java/src/com/android/inputmethod/keyboard/Keyboard.java
@@ -20,6 +20,7 @@ import android.content.Context;
import android.content.res.Resources;
import android.content.res.TypedArray;
import android.content.res.XmlResourceParser;
+import android.text.TextUtils;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.util.Log;
@@ -38,10 +39,12 @@ import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
import java.io.IOException;
+import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
+import java.util.List;
import java.util.Map;
import java.util.Set;
@@ -130,6 +133,8 @@ public class Keyboard {
private final ProximityInfo mProximityInfo;
+ public final Map<Integer, List<Integer>> mAdditionalProximityChars;
+
public Keyboard(Params params) {
mId = params.mId;
mThemeId = params.mThemeId;
@@ -146,10 +151,12 @@ public class Keyboard {
mKeys = Collections.unmodifiableSet(params.mKeys);
mShiftKeys = Collections.unmodifiableSet(params.mShiftKeys);
mIconsSet = params.mIconsSet;
+ mAdditionalProximityChars = params.mAdditionalProximityChars;
mProximityInfo = new ProximityInfo(
params.GRID_WIDTH, params.GRID_HEIGHT, mOccupiedWidth, mOccupiedHeight,
- mMostCommonKeyWidth, mMostCommonKeyHeight, mKeys, params.mTouchPositionCorrection);
+ mMostCommonKeyWidth, mMostCommonKeyHeight, mKeys, params.mTouchPositionCorrection,
+ params.mAdditionalProximityChars);
}
public ProximityInfo getProximityInfo() {
@@ -227,6 +234,9 @@ public class Keyboard {
public final Set<Key> mKeys = new HashSet<Key>();
public final Set<Key> mShiftKeys = new HashSet<Key>();
public final KeyboardIconsSet mIconsSet = new KeyboardIconsSet();
+ // TODO: Should be in Key instead of Keyboard.Params?
+ public final Map<Integer, List<Integer>> mAdditionalProximityChars =
+ new HashMap<Integer, List<Integer>>();
public KeyboardSet.KeysCache mKeysCache;
@@ -358,6 +368,10 @@ public class Keyboard {
return mProximityInfo.getNearestKeys(adjustedX, adjustedY);
}
+ public Map<Integer, List<Integer>> getAdditionalProximityChars() {
+ return mAdditionalProximityChars;
+ }
+
public static String printableCode(int code) {
switch (code) {
case CODE_SHIFT: return "shift";
@@ -614,6 +628,7 @@ public class Keyboard {
mParams = params;
setTouchPositionCorrectionData(context, params);
+ setAdditionalProximityChars(context, params);
params.GRID_WIDTH = res.getInteger(R.integer.config_keyboard_grid_width);
params.GRID_HEIGHT = res.getInteger(R.integer.config_keyboard_grid_height);
@@ -636,6 +651,25 @@ public class Keyboard {
params.mTouchPositionCorrection.load(data);
}
+ private static void setAdditionalProximityChars(Context context, Params params) {
+ final String[] additionalChars =
+ context.getResources().getStringArray(R.array.additional_proximitychars);
+ int currentPrimaryIndex = 0;
+ for (int i = 0; i < additionalChars.length; ++i) {
+ final String additionalChar = additionalChars[i];
+ if (TextUtils.isEmpty(additionalChar)) {
+ currentPrimaryIndex = 0;
+ } else if (currentPrimaryIndex == 0) {
+ currentPrimaryIndex = additionalChar.charAt(0);
+ params.mAdditionalProximityChars.put(
+ currentPrimaryIndex, new ArrayList<Integer>());
+ } else if (currentPrimaryIndex != 0) {
+ final int c = additionalChar.charAt(0);
+ params.mAdditionalProximityChars.get(currentPrimaryIndex).add(c);
+ }
+ }
+ }
+
public void setAutoGenerate(KeyboardSet.KeysCache keysCache) {
mParams.mKeysCache = keysCache;
}
diff --git a/java/src/com/android/inputmethod/keyboard/ProximityInfo.java b/java/src/com/android/inputmethod/keyboard/ProximityInfo.java
index c1dae0601..2d1a0083d 100644
--- a/java/src/com/android/inputmethod/keyboard/ProximityInfo.java
+++ b/java/src/com/android/inputmethod/keyboard/ProximityInfo.java
@@ -24,6 +24,9 @@ import com.android.inputmethod.latin.spellcheck.SpellCheckerProximityInfo;
import java.util.Arrays;
import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
import java.util.Set;
public class ProximityInfo {
@@ -44,7 +47,8 @@ public class ProximityInfo {
private final Key[][] mGridNeighbors;
ProximityInfo(int gridWidth, int gridHeight, int minWidth, int height, int keyWidth,
- int keyHeight, Set<Key> keys, TouchPositionCorrection touchPositionCorrection) {
+ int keyHeight, Set<Key> keys, TouchPositionCorrection touchPositionCorrection,
+ Map<Integer, List<Integer>> additionalProximityChars) {
mGridWidth = gridWidth;
mGridHeight = gridHeight;
mGridSize = mGridWidth * mGridHeight;
@@ -58,20 +62,20 @@ public class ProximityInfo {
// No proximity required. Keyboard might be mini keyboard.
return;
}
- computeNearestNeighbors(keyWidth, keys, touchPositionCorrection);
+ computeNearestNeighbors(keyWidth, keys, touchPositionCorrection, additionalProximityChars);
}
public static ProximityInfo createDummyProximityInfo() {
- return new ProximityInfo(1, 1, 1, 1, 1, 1, Collections.<Key>emptySet(), null);
+ return new ProximityInfo(1, 1, 1, 1, 1, 1, Collections.<Key> emptySet(),
+ null, Collections.<Integer, List<Integer>> emptyMap());
}
public static ProximityInfo createSpellCheckerProximityInfo(final int[] proximity) {
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, proximity, 0,
+ null, null, null, null, null, null, null, null);
return spellCheckerProximityInfo;
}
@@ -79,11 +83,13 @@ public class ProximityInfo {
static {
Utils.loadNativeLibrary();
}
+
private native long 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,
float[] sweetSpotCenterX, float[] sweetSpotCenterY, float[] sweetSpotRadii);
+
private native void releaseProximityInfoNative(long nativeProximityInfo);
private final void setProximityInfo(Key[][] gridNeighborKeys, int keyboardWidth,
@@ -138,7 +144,7 @@ public class ProximityInfo {
final float radius = touchPositionCorrection.mRadii[row];
sweetSpotCenterXs[i] = hitBoxCenterX + x * hitBoxWidth;
sweetSpotCenterYs[i] = hitBoxCenterY + y * hitBoxHeight;
- sweetSpotRadii[i] = radius * (float)Math.sqrt(
+ sweetSpotRadii[i] = radius * (float) Math.sqrt(
hitBoxWidth * hitBoxWidth + hitBoxHeight * hitBoxHeight);
}
}
@@ -168,7 +174,12 @@ public class ProximityInfo {
}
private void computeNearestNeighbors(int defaultWidth, Set<Key> keys,
- TouchPositionCorrection touchPositionCorrection) {
+ TouchPositionCorrection touchPositionCorrection,
+ Map<Integer, List<Integer>> additionalProximityChars) {
+ final Map<Integer, Key> keyCodeMap = new HashMap<Integer, Key>();
+ for (final Key key : keys) {
+ keyCodeMap.put(key.mCode, key);
+ }
final int thresholdBase = (int) (defaultWidth * SEARCH_DISTANCE);
final int threshold = thresholdBase * thresholdBase;
// Round-up so we don't have any pixels outside the grid
@@ -186,6 +197,27 @@ public class ProximityInfo {
neighborKeys[count++] = key;
}
}
+ int currentCodesSize = count;
+ for (int i = 0; i < currentCodesSize; ++i) {
+ final int c = neighborKeys[i].mCode;
+ final List<Integer> additionalChars = additionalProximityChars.get(c);
+ if (additionalChars == null || additionalChars.size() == 0) {
+ continue;
+ }
+ for (int j = 0; j < additionalChars.size(); ++j) {
+ final int additionalChar = additionalChars.get(j);
+ boolean contains = false;
+ for (int k = 0; k < count; ++k) {
+ if(additionalChar == neighborKeys[k].mCode) {
+ contains = true;
+ break;
+ }
+ }
+ if (!contains) {
+ neighborKeys[count++] = keyCodeMap.get(additionalChar);
+ }
+ }
+ }
mGridNeighbors[(y / mCellHeight) * mGridWidth + (x / mCellWidth)] =
Arrays.copyOfRange(neighborKeys, 0, count);
}
@@ -199,7 +231,7 @@ public class ProximityInfo {
return EMPTY_KEY_ARRAY;
}
if (x >= 0 && x < mKeyboardMinWidth && y >= 0 && y < mKeyboardHeight) {
- int index = (y / mCellHeight) * mGridWidth + (x / mCellWidth);
+ int index = (y / mCellHeight) * mGridWidth + (x / mCellWidth);
if (index < mGridSize) {
return mGridNeighbors[index];
}
diff --git a/java/src/com/android/inputmethod/latin/WordComposer.java b/java/src/com/android/inputmethod/latin/WordComposer.java
index 230c2916b..bd244b913 100644
--- a/java/src/com/android/inputmethod/latin/WordComposer.java
+++ b/java/src/com/android/inputmethod/latin/WordComposer.java
@@ -16,8 +16,6 @@
package com.android.inputmethod.latin;
-import android.text.TextUtils;
-
import com.android.inputmethod.keyboard.Key;
import com.android.inputmethod.keyboard.KeyDetector;
import com.android.inputmethod.keyboard.Keyboard;
@@ -33,7 +31,7 @@ public class WordComposer {
public static final int NOT_A_CODE = KeyDetector.NOT_A_CODE;
public static final int NOT_A_COORDINATE = -1;
- final int N = BinaryDictionary.MAX_WORD_LENGTH;
+ final static int N = BinaryDictionary.MAX_WORD_LENGTH;
private ArrayList<int[]> mCodes;
private int[] mXCoordinates;