Merge "Create proximity info just after parsing keyboard layouts"

This commit is contained in:
satok 2011-07-12 00:57:06 -07:00 committed by Android (Google) Code Review
commit 8275fb0a1a
2 changed files with 65 additions and 57 deletions

View file

@ -141,14 +141,6 @@ public class Keyboard {
// TODO: Change GRID_WIDTH and GRID_HEIGHT to private. // TODO: Change GRID_WIDTH and GRID_HEIGHT to private.
public final int GRID_WIDTH; public final int GRID_WIDTH;
public final int GRID_HEIGHT; public final int GRID_HEIGHT;
private final int GRID_SIZE;
private int mCellWidth;
private int mCellHeight;
private int[][] mGridNeighbors;
private int mProximityThreshold;
private static int[] EMPTY_INT_ARRAY = new int[0];
/** Number of key widths from current touch point to search for nearest keys. */
private static float SEARCH_DISTANCE = 1.2f;
private final ProximityInfo mProximityInfo; private final ProximityInfo mProximityInfo;
@ -164,7 +156,6 @@ public class Keyboard {
final Resources res = context.getResources(); final Resources res = context.getResources();
GRID_WIDTH = res.getInteger(R.integer.config_keyboard_grid_width); GRID_WIDTH = res.getInteger(R.integer.config_keyboard_grid_width);
GRID_HEIGHT = res.getInteger(R.integer.config_keyboard_grid_height); GRID_HEIGHT = res.getInteger(R.integer.config_keyboard_grid_height);
GRID_SIZE = GRID_WIDTH * GRID_HEIGHT;
final int horizontalEdgesPadding = (int)res.getDimension( final int horizontalEdgesPadding = (int)res.getDimension(
R.dimen.keyboard_horizontal_edges_padding); R.dimen.keyboard_horizontal_edges_padding);
@ -177,12 +168,13 @@ public class Keyboard {
mDefaultVerticalGap = 0; mDefaultVerticalGap = 0;
mDefaultHeight = mDefaultWidth; mDefaultHeight = mDefaultWidth;
mId = id; mId = id;
mProximityInfo = new ProximityInfo(GRID_WIDTH, GRID_HEIGHT);
loadKeyboard(context, xmlLayoutResId); loadKeyboard(context, xmlLayoutResId);
mProximityInfo = new ProximityInfo(
GRID_WIDTH, GRID_HEIGHT, getMinWidth(), getHeight(), getKeyWidth(), mKeys);
} }
public int getProximityInfo() { public int getProximityInfo() {
return mProximityInfo.getNativeProximityInfo(this); return mProximityInfo.getNativeProximityInfo();
} }
public List<Key> getKeys() { public List<Key> getKeys() {
@ -219,8 +211,6 @@ public class Keyboard {
public void setKeyWidth(int width) { public void setKeyWidth(int width) {
mDefaultWidth = width; mDefaultWidth = width;
final int threshold = (int) (width * SEARCH_DISTANCE);
mProximityThreshold = threshold * threshold;
} }
/** /**
@ -365,34 +355,6 @@ public class Keyboard {
return label; return label;
} }
// TODO: Move this function to ProximityInfo and make this private.
public void computeNearestNeighbors() {
// Round-up so we don't have any pixels outside the grid
mCellWidth = (getMinWidth() + GRID_WIDTH - 1) / GRID_WIDTH;
mCellHeight = (getHeight() + GRID_HEIGHT - 1) / GRID_HEIGHT;
mGridNeighbors = new int[GRID_SIZE][];
final int[] indices = new int[mKeys.size()];
final int gridWidth = GRID_WIDTH * mCellWidth;
final int gridHeight = GRID_HEIGHT * mCellHeight;
final int threshold = mProximityThreshold;
for (int x = 0; x < gridWidth; x += mCellWidth) {
for (int y = 0; y < gridHeight; y += mCellHeight) {
final int centerX = x + mCellWidth / 2;
final int centerY = y + mCellHeight / 2;
int count = 0;
for (int i = 0; i < mKeys.size(); i++) {
final Key key = mKeys.get(i);
if (key.squaredDistanceToEdge(centerX, centerY) < threshold)
indices[count++] = i;
}
final int[] cell = new int[count];
System.arraycopy(indices, 0, cell, 0, count);
mGridNeighbors[(y / mCellHeight) * GRID_WIDTH + (x / mCellWidth)] = cell;
}
}
mProximityInfo.setProximityInfo(mGridNeighbors, getMinWidth(), getHeight(), mKeys);
}
/** /**
* Returns the indices of the keys that are closest to the given point. * Returns the indices 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
@ -401,14 +363,7 @@ public class Keyboard {
* 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 int[] getNearestKeys(int x, int y) {
if (mGridNeighbors == null) computeNearestNeighbors(); return mProximityInfo.getNearestKeys(x, y);
if (x >= 0 && x < getMinWidth() && y >= 0 && y < getHeight()) {
int index = (y / mCellHeight) * GRID_WIDTH + (x / mCellWidth);
if (index < GRID_SIZE) {
return mGridNeighbors[index];
}
}
return EMPTY_INT_ARRAY;
} }
/** /**

View file

@ -23,15 +23,35 @@ import java.util.List;
public class ProximityInfo { 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. */
private static float SEARCH_DISTANCE = 1.2f;
private static final int[] EMPTY_INT_ARRAY = new int[0];
private final int mGridWidth; private final int mGridWidth;
private final int mGridHeight; private final int mGridHeight;
private final int mGridSize; private final int mGridSize;
private final int mCellWidth;
private final int mCellHeight;
// TODO: Find a proper name for mKeyboardMinWidth
private final int mKeyboardMinWidth;
private final int mKeyboardHeight;
private final int[][] mGridNeighbors;
ProximityInfo(int gridWidth, int gridHeight) { ProximityInfo(
int gridWidth, int gridHeight, int minWidth, int height, int keyWidth, List<Key> keys) {
mGridWidth = gridWidth; mGridWidth = gridWidth;
mGridHeight = gridHeight; mGridHeight = gridHeight;
mGridSize = mGridWidth * mGridHeight; mGridSize = mGridWidth * mGridHeight;
mCellWidth = (minWidth + mGridWidth - 1) / mGridWidth;
mCellHeight = (height + mGridHeight - 1) / mGridHeight;
mKeyboardMinWidth = minWidth;
mKeyboardHeight = height;
mGridNeighbors = new int[mGridSize][];
if (minWidth == 0 || height == 0) {
// No proximity required. Keyboard might be mini keyboard.
return;
}
computeNearestNeighbors(keyWidth, keys);
} }
private int mNativeProximityInfo; private int mNativeProximityInfo;
@ -42,7 +62,7 @@ public class ProximityInfo {
int displayHeight, int gridWidth, int gridHeight, int[] proximityCharsArray); int displayHeight, int gridWidth, int gridHeight, int[] proximityCharsArray);
private native void releaseProximityInfoNative(int nativeProximityInfo); private native void releaseProximityInfoNative(int nativeProximityInfo);
public final void setProximityInfo(int[][] gridNeighborKeyIndexes, int keyboardWidth, private final void setProximityInfo(int[][] gridNeighborKeyIndexes, int keyboardWidth,
int keyboardHeight, List<Key> keys) { int keyboardHeight, List<Key> keys) {
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);
@ -57,12 +77,7 @@ public class ProximityInfo {
keyboardWidth, keyboardHeight, mGridWidth, mGridHeight, proximityCharsArray); keyboardWidth, keyboardHeight, mGridWidth, mGridHeight, proximityCharsArray);
} }
// TODO: Get rid of this function's input (keyboard). public int getNativeProximityInfo() {
public int getNativeProximityInfo(Keyboard keyboard) {
if (mNativeProximityInfo == 0) {
// TODO: Move this function to ProximityInfo and make this private.
keyboard.computeNearestNeighbors();
}
return mNativeProximityInfo; return mNativeProximityInfo;
} }
@ -77,4 +92,42 @@ public class ProximityInfo {
super.finalize(); super.finalize();
} }
} }
private void computeNearestNeighbors(int defaultWidth, List<Key> keys) {
final int thresholdBase = (int) (defaultWidth * SEARCH_DISTANCE);
final int threshold = thresholdBase * thresholdBase;
// Round-up so we don't have any pixels outside the grid
final int[] indices = new int[keys.size()];
final int gridWidth = mGridWidth * mCellWidth;
final int gridHeight = mGridHeight * mCellHeight;
for (int x = 0; x < gridWidth; x += mCellWidth) {
for (int y = 0; y < gridHeight; y += mCellHeight) {
final int centerX = x + mCellWidth / 2;
final int centerY = y + mCellHeight / 2;
int count = 0;
for (int i = 0; i < keys.size(); i++) {
final Key key = keys.get(i);
if (key.squaredDistanceToEdge(centerX, centerY) < threshold)
indices[count++] = i;
}
final int[] cell = new int[count];
System.arraycopy(indices, 0, cell, 0, count);
mGridNeighbors[(y / mCellHeight) * mGridWidth + (x / mCellWidth)] = cell;
}
}
setProximityInfo(mGridNeighbors, mKeyboardMinWidth, mKeyboardHeight, keys);
}
public int[] getNearestKeys(int x, int y) {
if (mGridNeighbors == null) {
return EMPTY_INT_ARRAY;
}
if (x >= 0 && x < mKeyboardMinWidth && y >= 0 && y < mKeyboardHeight) {
int index = (y / mCellHeight) * mGridWidth + (x / mCellWidth);
if (index < mGridSize) {
return mGridNeighbors[index];
}
}
return EMPTY_INT_ARRAY;
}
} }