Get rid of key index from ProxymityInfo

Change-Id: I9bee0a643d09cdd89e42ae913285c9e78d875c1c
main
Tadashi G. Takaoka 2011-12-16 14:20:11 +09:00
parent bf7ed75e4f
commit 0c0ca874fe
4 changed files with 38 additions and 44 deletions

View File

@ -19,14 +19,12 @@ package com.android.inputmethod.keyboard;
import android.util.Log; import android.util.Log;
import java.util.Arrays; import java.util.Arrays;
import java.util.List;
public class KeyDetector { public class KeyDetector {
private static final String TAG = KeyDetector.class.getSimpleName(); private static final String TAG = KeyDetector.class.getSimpleName();
private static final boolean DEBUG = false; private static final boolean DEBUG = false;
public static final int NOT_A_CODE = -1; public static final int NOT_A_CODE = -1;
private static final int NOT_A_KEY = -1;
private final int mKeyHysteresisDistanceSquared; private final int mKeyHysteresisDistanceSquared;
@ -39,7 +37,7 @@ public class KeyDetector {
// working area // working area
private static final int MAX_NEARBY_KEYS = 12; private static final int MAX_NEARBY_KEYS = 12;
private final int[] mDistances = new int[MAX_NEARBY_KEYS]; private final int[] mDistances = new int[MAX_NEARBY_KEYS];
private final int[] mIndices = new int[MAX_NEARBY_KEYS]; private final Key[] mNeighborKeys = new Key[MAX_NEARBY_KEYS];
/** /**
* This class handles key detection. * This class handles key detection.
@ -122,7 +120,7 @@ public class KeyDetector {
private void initializeNearbyKeys() { private void initializeNearbyKeys() {
Arrays.fill(mDistances, Integer.MAX_VALUE); Arrays.fill(mDistances, Integer.MAX_VALUE);
Arrays.fill(mIndices, NOT_A_KEY); Arrays.fill(mNeighborKeys, null);
} }
/** /**
@ -130,14 +128,14 @@ public class KeyDetector {
* If the distance of two keys are the same, the key which the point is on should be considered * If the distance of two keys are the same, the key which the point is on should be considered
* as a closer one. * as a closer one.
* *
* @param keyIndex index of the key. * @param key the key to be inserted into the nearby keys buffer.
* @param distance distance between the key's edge and user touched point. * @param distance distance between the key's edge and user touched point.
* @param isOnKey true if the point is on the key. * @param isOnKey true if the point is on the key.
* @return order of the key in the nearby buffer, 0 if it is the nearest key. * @return order of the key in the nearby buffer, 0 if it is the nearest key.
*/ */
private int sortNearbyKeys(int keyIndex, int distance, boolean isOnKey) { private int sortNearbyKeys(Key key, int distance, boolean isOnKey) {
final int[] distances = mDistances; final int[] distances = mDistances;
final int[] indices = mIndices; final Key[] neighborKeys = mNeighborKeys;
for (int insertPos = 0; insertPos < distances.length; insertPos++) { for (int insertPos = 0; insertPos < distances.length; insertPos++) {
final int comparingDistance = distances[insertPos]; final int comparingDistance = distances[insertPos];
if (distance < comparingDistance || (distance == comparingDistance && isOnKey)) { if (distance < comparingDistance || (distance == comparingDistance && isOnKey)) {
@ -145,11 +143,11 @@ public class KeyDetector {
if (nextPos < distances.length) { if (nextPos < distances.length) {
System.arraycopy(distances, insertPos, distances, nextPos, System.arraycopy(distances, insertPos, distances, nextPos,
distances.length - nextPos); distances.length - nextPos);
System.arraycopy(indices, insertPos, indices, nextPos, System.arraycopy(neighborKeys, insertPos, neighborKeys, nextPos,
indices.length - nextPos); neighborKeys.length - nextPos);
} }
distances[insertPos] = distance; distances[insertPos] = distance;
indices[insertPos] = keyIndex; neighborKeys[insertPos] = key;
return insertPos; return insertPos;
} }
} }
@ -157,21 +155,20 @@ public class KeyDetector {
} }
private void getNearbyKeyCodes(final int[] allCodes) { private void getNearbyKeyCodes(final int[] allCodes) {
final List<Key> keys = getKeyboard().mKeys; final Key[] neighborKeys = mNeighborKeys;
final int[] indices = mIndices;
// allCodes[0] should always have the key code even if it is a non-letter key. // allCodes[0] should always have the key code even if it is a non-letter key.
if (indices[0] == NOT_A_KEY) { if (neighborKeys[0] == null) {
allCodes[0] = NOT_A_CODE; allCodes[0] = NOT_A_CODE;
return; return;
} }
int numCodes = 0; int numCodes = 0;
for (int j = 0; j < indices.length && numCodes < allCodes.length; j++) { for (int j = 0; j < neighborKeys.length && numCodes < allCodes.length; j++) {
final int index = indices[j]; final Key key = neighborKeys[j];
if (index == NOT_A_KEY) if (key == null)
break; break;
final int code = keys.get(index).mCode; final int code = key.mCode;
// filter out a non-letter key from nearby keys // filter out a non-letter key from nearby keys
if (code < Keyboard.CODE_SPACE) if (code < Keyboard.CODE_SPACE)
continue; continue;
@ -191,18 +188,16 @@ public class KeyDetector {
* @return The nearest key * @return The nearest key
*/ */
public Key getKeyAndNearbyCodes(int x, int y, final int[] allCodes) { public Key getKeyAndNearbyCodes(int x, int y, final int[] allCodes) {
final List<Key> keys = getKeyboard().mKeys;
final int touchX = getTouchX(x); final int touchX = getTouchX(x);
final int touchY = getTouchY(y); final int touchY = getTouchY(y);
initializeNearbyKeys(); initializeNearbyKeys();
Key primaryKey = null; Key primaryKey = null;
for (final int index : mKeyboard.getNearestKeys(touchX, touchY)) { for (final Key key: mKeyboard.getNearestKeys(touchX, touchY)) {
final Key key = keys.get(index);
final boolean isOnKey = key.isOnKey(touchX, touchY); final boolean isOnKey = key.isOnKey(touchX, touchY);
final int distance = key.squaredDistanceToEdge(touchX, touchY); final int distance = key.squaredDistanceToEdge(touchX, touchY);
if (isOnKey || (mProximityCorrectOn && distance < mProximityThresholdSquare)) { if (isOnKey || (mProximityCorrectOn && distance < mProximityThresholdSquare)) {
final int insertedPosition = sortNearbyKeys(index, distance, isOnKey); final int insertedPosition = sortNearbyKeys(key, distance, isOnKey);
if (insertedPosition == 0 && isOnKey) { if (insertedPosition == 0 && isOnKey) {
primaryKey = key; primaryKey = key;
} }

View File

@ -225,13 +225,13 @@ public class Keyboard {
} }
/** /**
* Returns the indices of the keys that are closest to the given point. * Returns the array of the keys that are closest to the given point.
* @param x the x-coordinate of the point * @param x the x-coordinate of the point
* @param y the y-coordinate of the point * @param y the y-coordinate of the point
* @return the array of integer indices for the nearest keys to the given point. If the given * @return the array of the nearest keys to the given point. If the given
* point is out of range, then an array of size zero is returned. * point is out of range, then an array of size zero is returned.
*/ */
public int[] getNearestKeys(int x, int y) { public Key[] getNearestKeys(int x, int y) {
return mProximityInfo.getNearestKeys(x, y); return mProximityInfo.getNearestKeys(x, y);
} }

View File

@ -106,8 +106,8 @@ public class LatinKeyboard extends Keyboard {
} }
private static class LatinKeyboardParams extends KeyboardParams { private static class LatinKeyboardParams extends KeyboardParams {
public Key mSpaceKey = null; Key mSpaceKey = null;
public Key mShortcutKey = null; Key mShortcutKey = null;
LatinKeyboardParams() {} LatinKeyboardParams() {}
@ -323,7 +323,7 @@ public class LatinKeyboard extends Keyboard {
} }
@Override @Override
public int[] getNearestKeys(int x, int y) { public Key[] getNearestKeys(int x, int y) {
// Avoid dead pixels at edges of the keyboard // Avoid dead pixels at edges of the keyboard
return super.getNearestKeys(Math.max(0, Math.min(x, mOccupiedWidth - 1)), return super.getNearestKeys(Math.max(0, Math.min(x, mOccupiedWidth - 1)),
Math.max(0, Math.min(y, mOccupiedHeight - 1))); Math.max(0, Math.min(y, mOccupiedHeight - 1)));

View File

@ -30,7 +30,7 @@ public class ProximityInfo {
public static final int MAX_PROXIMITY_CHARS_SIZE = 16; public static final int MAX_PROXIMITY_CHARS_SIZE = 16;
/** Number of key widths from current touch point to search for nearest keys. */ /** Number of key widths from current touch point to search for nearest keys. */
private static float SEARCH_DISTANCE = 1.2f; private static float SEARCH_DISTANCE = 1.2f;
private static final int[] EMPTY_INT_ARRAY = new int[0]; private static final Key[] EMPTY_KEY_ARRAY = new Key[0];
private final int mKeyHeight; private final int mKeyHeight;
private final int mGridWidth; private final int mGridWidth;
@ -41,7 +41,7 @@ public class ProximityInfo {
// TODO: Find a proper name for mKeyboardMinWidth // TODO: Find a proper name for mKeyboardMinWidth
private final int mKeyboardMinWidth; private final int mKeyboardMinWidth;
private final int mKeyboardHeight; private final int mKeyboardHeight;
private final int[][] mGridNeighbors; private final Key[][] mGridNeighbors;
ProximityInfo(int gridWidth, int gridHeight, int minWidth, int height, int keyWidth, ProximityInfo(int gridWidth, int gridHeight, int minWidth, int height, int keyWidth,
int keyHeight, List<Key> keys, TouchPositionCorrection touchPositionCorrection) { int keyHeight, List<Key> keys, TouchPositionCorrection touchPositionCorrection) {
@ -53,7 +53,7 @@ public class ProximityInfo {
mKeyboardMinWidth = minWidth; mKeyboardMinWidth = minWidth;
mKeyboardHeight = height; mKeyboardHeight = height;
mKeyHeight = keyHeight; mKeyHeight = keyHeight;
mGridNeighbors = new int[mGridSize][]; mGridNeighbors = new Key[mGridSize][];
if (minWidth == 0 || height == 0) { if (minWidth == 0 || height == 0) {
// No proximity required. Keyboard might be mini keyboard. // No proximity required. Keyboard might be mini keyboard.
return; return;
@ -86,16 +86,16 @@ public class ProximityInfo {
float[] sweetSpotCenterX, float[] sweetSpotCenterY, float[] sweetSpotRadii); float[] sweetSpotCenterX, float[] sweetSpotCenterY, float[] sweetSpotRadii);
private native void releaseProximityInfoNative(long nativeProximityInfo); private native void releaseProximityInfoNative(long nativeProximityInfo);
private final void setProximityInfo(int[][] gridNeighborKeyIndexes, int keyboardWidth, private final void setProximityInfo(Key[][] gridNeighborKeys, int keyboardWidth,
int keyboardHeight, List<Key> keys, int keyboardHeight, List<Key> keys,
TouchPositionCorrection touchPositionCorrection) { TouchPositionCorrection touchPositionCorrection) {
int[] proximityCharsArray = new int[mGridSize * MAX_PROXIMITY_CHARS_SIZE]; int[] proximityCharsArray = new int[mGridSize * MAX_PROXIMITY_CHARS_SIZE];
Arrays.fill(proximityCharsArray, KeyDetector.NOT_A_CODE); Arrays.fill(proximityCharsArray, KeyDetector.NOT_A_CODE);
for (int i = 0; i < mGridSize; ++i) { for (int i = 0; i < mGridSize; ++i) {
final int proximityCharsLength = gridNeighborKeyIndexes[i].length; final int proximityCharsLength = gridNeighborKeys[i].length;
for (int j = 0; j < proximityCharsLength; ++j) { for (int j = 0; j < proximityCharsLength; ++j) {
proximityCharsArray[i * MAX_PROXIMITY_CHARS_SIZE + j] = proximityCharsArray[i * MAX_PROXIMITY_CHARS_SIZE + j] =
keys.get(gridNeighborKeyIndexes[i][j]).mCode; gridNeighborKeys[i][j].mCode;
} }
} }
final int keyCount = keys.size(); final int keyCount = keys.size();
@ -171,7 +171,7 @@ public class ProximityInfo {
final int thresholdBase = (int) (defaultWidth * SEARCH_DISTANCE); final int thresholdBase = (int) (defaultWidth * SEARCH_DISTANCE);
final int threshold = thresholdBase * thresholdBase; final int threshold = thresholdBase * thresholdBase;
// Round-up so we don't have any pixels outside the grid // Round-up so we don't have any pixels outside the grid
final int[] indices = new int[keys.size()]; final Key[] neighborKeys = new Key[keys.size()];
final int gridWidth = mGridWidth * mCellWidth; final int gridWidth = mGridWidth * mCellWidth;
final int gridHeight = mGridHeight * mCellHeight; final int gridHeight = mGridHeight * mCellHeight;
for (int x = 0; x < gridWidth; x += mCellWidth) { for (int x = 0; x < gridWidth; x += mCellWidth) {
@ -179,24 +179,23 @@ public class ProximityInfo {
final int centerX = x + mCellWidth / 2; final int centerX = x + mCellWidth / 2;
final int centerY = y + mCellHeight / 2; final int centerY = y + mCellHeight / 2;
int count = 0; int count = 0;
for (int i = 0; i < keys.size(); i++) { for (final Key key : keys) {
final Key key = keys.get(i);
if (key.isSpacer()) continue; if (key.isSpacer()) continue;
if (key.squaredDistanceToEdge(centerX, centerY) < threshold) if (key.squaredDistanceToEdge(centerX, centerY) < threshold) {
indices[count++] = i; neighborKeys[count++] = key;
}
} }
final int[] cell = new int[count]; mGridNeighbors[(y / mCellHeight) * mGridWidth + (x / mCellWidth)] =
System.arraycopy(indices, 0, cell, 0, count); Arrays.copyOfRange(neighborKeys, 0, count);
mGridNeighbors[(y / mCellHeight) * mGridWidth + (x / mCellWidth)] = cell;
} }
} }
setProximityInfo(mGridNeighbors, mKeyboardMinWidth, mKeyboardHeight, keys, setProximityInfo(mGridNeighbors, mKeyboardMinWidth, mKeyboardHeight, keys,
touchPositionCorrection); touchPositionCorrection);
} }
public int[] getNearestKeys(int x, int y) { public Key[] getNearestKeys(int x, int y) {
if (mGridNeighbors == null) { if (mGridNeighbors == null) {
return EMPTY_INT_ARRAY; return EMPTY_KEY_ARRAY;
} }
if (x >= 0 && x < mKeyboardMinWidth && y >= 0 && y < mKeyboardHeight) { if (x >= 0 && x < mKeyboardMinWidth && y >= 0 && y < mKeyboardHeight) {
int index = (y / mCellHeight) * mGridWidth + (x / mCellWidth); int index = (y / mCellHeight) * mGridWidth + (x / mCellWidth);
@ -204,6 +203,6 @@ public class ProximityInfo {
return mGridNeighbors[index]; return mGridNeighbors[index];
} }
} }
return EMPTY_INT_ARRAY; return EMPTY_KEY_ARRAY;
} }
} }