Merge "Calculate proximity characters in the native code"
This commit is contained in:
commit
a50a34f8b4
4 changed files with 77 additions and 26 deletions
|
@ -260,12 +260,19 @@ public class KeyDetector {
|
||||||
final int touchX = getTouchX(x);
|
final int touchX = getTouchX(x);
|
||||||
final int touchY = getTouchY(y);
|
final int touchY = getTouchY(y);
|
||||||
|
|
||||||
for (final Key key : mKeyboard.getNearestKeys(touchX, touchY)) {
|
int minDistance = Integer.MAX_VALUE;
|
||||||
if (key.isOnKey(touchX, touchY)) {
|
Key primaryKey = null;
|
||||||
return key;
|
for (final Key key: mKeyboard.getNearestKeys(touchX, touchY)) {
|
||||||
|
final boolean isOnKey = key.isOnKey(touchX, touchY);
|
||||||
|
final int distance = key.squaredDistanceToEdge(touchX, touchY);
|
||||||
|
// TODO: need to take care of hitbox overlaps
|
||||||
|
if (primaryKey == null || distance < minDistance
|
||||||
|
|| (distance == minDistance && isOnKey)) {
|
||||||
|
minDistance = distance;
|
||||||
|
primaryKey = key;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return null;
|
return primaryKey;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String printableCode(Key key) {
|
public static String printableCode(Key key) {
|
||||||
|
|
|
@ -140,8 +140,8 @@ public class WordComposer {
|
||||||
keyX = x;
|
keyX = x;
|
||||||
keyY = y;
|
keyY = y;
|
||||||
} else {
|
} else {
|
||||||
codes = keyDetector.newCodeArray();
|
final Key key = keyDetector.detectHitKey(x, y);
|
||||||
keyDetector.getNearbyCodes(x, y, codes);
|
codes = new int[] { key != null ? key.mCode : NOT_A_CODE };
|
||||||
keyX = keyDetector.getTouchX(x);
|
keyX = keyDetector.getTouchX(x);
|
||||||
keyY = keyDetector.getTouchY(y);
|
keyY = keyDetector.getTouchY(y);
|
||||||
}
|
}
|
||||||
|
|
|
@ -55,6 +55,7 @@ ProximityInfo::ProximityInfo(const std::string localeStr, const int maxProximity
|
||||||
mTouchPositionCorrectionEnabled(false) {
|
mTouchPositionCorrectionEnabled(false) {
|
||||||
const int proximityGridLength = GRID_WIDTH * GRID_HEIGHT * MAX_PROXIMITY_CHARS_SIZE;
|
const int proximityGridLength = GRID_WIDTH * GRID_HEIGHT * MAX_PROXIMITY_CHARS_SIZE;
|
||||||
mProximityCharsArray = new int32_t[proximityGridLength];
|
mProximityCharsArray = new int32_t[proximityGridLength];
|
||||||
|
mInputCodes = new int32_t[MAX_PROXIMITY_CHARS_SIZE * MAX_WORD_LENGTH_INTERNAL];
|
||||||
if (DEBUG_PROXIMITY_INFO) {
|
if (DEBUG_PROXIMITY_INFO) {
|
||||||
AKLOGI("Create proximity info array %d", proximityGridLength);
|
AKLOGI("Create proximity info array %d", proximityGridLength);
|
||||||
}
|
}
|
||||||
|
@ -96,6 +97,7 @@ void ProximityInfo::initializeCodeToKeyIndex() {
|
||||||
ProximityInfo::~ProximityInfo() {
|
ProximityInfo::~ProximityInfo() {
|
||||||
delete[] mNormalizedSquaredDistances;
|
delete[] mNormalizedSquaredDistances;
|
||||||
delete[] mProximityCharsArray;
|
delete[] mProximityCharsArray;
|
||||||
|
delete[] mInputCodes;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline int ProximityInfo::getStartIndexFromCoordinates(const int x, const int y) const {
|
inline int ProximityInfo::getStartIndexFromCoordinates(const int x, const int y) const {
|
||||||
|
@ -138,7 +140,7 @@ bool ProximityInfo::isOnKey(const int keyId, const int x, const int y) {
|
||||||
int ProximityInfo::squaredDistanceToEdge(const int keyId, const int x, const int y) {
|
int ProximityInfo::squaredDistanceToEdge(const int keyId, const int x, const int y) {
|
||||||
const int left = mKeyXCoordinates[keyId];
|
const int left = mKeyXCoordinates[keyId];
|
||||||
const int top = mKeyYCoordinates[keyId];
|
const int top = mKeyYCoordinates[keyId];
|
||||||
const int right = left + mKeyWidths[keyId] + 1;
|
const int right = left + mKeyWidths[keyId];
|
||||||
const int bottom = top + mKeyHeights[keyId];
|
const int bottom = top + mKeyHeights[keyId];
|
||||||
const int edgeX = x < left ? left : (x > right ? right : x);
|
const int edgeX = x < left ? left : (x > right ? right : x);
|
||||||
const int edgeY = y < top ? top : (y > bottom ? bottom : y);
|
const int edgeY = y < top ? top : (y > bottom ? bottom : y);
|
||||||
|
@ -157,10 +159,10 @@ void ProximityInfo::calculateNearbyKeyCodes(
|
||||||
if (c < KEYCODE_SPACE || c == primaryKey) {
|
if (c < KEYCODE_SPACE || c == primaryKey) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
int keyIndex = getKeyIndex(c);
|
const int keyIndex = getKeyIndex(c);
|
||||||
const bool onKey = isOnKey(keyIndex, x, y);
|
const bool onKey = isOnKey(keyIndex, x, y);
|
||||||
const int distance = squaredDistanceToEdge(keyIndex, x, y);
|
const int distance = squaredDistanceToEdge(keyIndex, x, y);
|
||||||
if (onKey || distance < MOST_COMMON_KEY_WIDTH_SQUARE) {
|
if (c >= KEYCODE_SPACE && (onKey || distance < MOST_COMMON_KEY_WIDTH_SQUARE)) {
|
||||||
inputCodes[insertPos++] = c;
|
inputCodes[insertPos++] = c;
|
||||||
if (insertPos >= MAX_PROXIMITY_CHARS_SIZE) {
|
if (insertPos >= MAX_PROXIMITY_CHARS_SIZE) {
|
||||||
if (DEBUG_DICT) {
|
if (DEBUG_DICT) {
|
||||||
|
@ -170,17 +172,17 @@ void ProximityInfo::calculateNearbyKeyCodes(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
inputCodes[insertPos++] = ADDITIONAL_PROXIMITY_CHAR_DELIMITER_CODE;
|
|
||||||
if (insertPos >= MAX_PROXIMITY_CHARS_SIZE) {
|
|
||||||
if (DEBUG_DICT) {
|
|
||||||
assert(false);
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const int additionalProximitySize =
|
const int additionalProximitySize =
|
||||||
AdditionalProximityChars::getAdditionalCharsSize(&mLocaleStr, primaryKey);
|
AdditionalProximityChars::getAdditionalCharsSize(&mLocaleStr, primaryKey);
|
||||||
if (additionalProximitySize > 0) {
|
if (additionalProximitySize > 0) {
|
||||||
|
inputCodes[insertPos++] = ADDITIONAL_PROXIMITY_CHAR_DELIMITER_CODE;
|
||||||
|
if (insertPos >= MAX_PROXIMITY_CHARS_SIZE) {
|
||||||
|
if (DEBUG_DICT) {
|
||||||
|
assert(false);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const int32_t* additionalProximityChars =
|
const int32_t* additionalProximityChars =
|
||||||
AdditionalProximityChars::getAdditionalChars(&mLocaleStr, primaryKey);
|
AdditionalProximityChars::getAdditionalChars(&mLocaleStr, primaryKey);
|
||||||
for (int j = 0; j < additionalProximitySize; ++j) {
|
for (int j = 0; j < additionalProximitySize; ++j) {
|
||||||
|
@ -204,13 +206,46 @@ void ProximityInfo::calculateNearbyKeyCodes(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Add a delimiter for the proximity characters
|
// Add a delimiter for the proximity characters
|
||||||
inputCodes[insertPos] = 0;
|
for (int i = insertPos; i < MAX_PROXIMITY_CHARS_SIZE; ++i) {
|
||||||
|
inputCodes[i] = NOT_A_CODE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Calculate nearby codes here.
|
// TODO: Calculate nearby codes here.
|
||||||
void ProximityInfo::setInputParams(const int* inputCodes, const int inputLength,
|
void ProximityInfo::setInputParams(const int32_t* inputCodes, const int inputLength,
|
||||||
const int* xCoordinates, const int* yCoordinates) {
|
const int* xCoordinates, const int* yCoordinates) {
|
||||||
mInputCodes = inputCodes;
|
memset(mInputCodes, 0,
|
||||||
|
MAX_WORD_LENGTH_INTERNAL * MAX_PROXIMITY_CHARS_SIZE * sizeof(mInputCodes[0]));
|
||||||
|
|
||||||
|
for (int i = 0; i < inputLength; ++i) {
|
||||||
|
const int32_t primaryKey = inputCodes[i * MAX_PROXIMITY_CHARS_SIZE];
|
||||||
|
const int x = xCoordinates[i];
|
||||||
|
const int y = yCoordinates[i];
|
||||||
|
int *proximities = &mInputCodes[i * MAX_PROXIMITY_CHARS_SIZE];
|
||||||
|
calculateNearbyKeyCodes(x, y, primaryKey, proximities);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (DEBUG_PROXIMITY_CHARS) {
|
||||||
|
for (int i = 0; i < inputLength; ++i) {
|
||||||
|
AKLOGI("---");
|
||||||
|
for (int j = 0; j < MAX_PROXIMITY_CHARS_SIZE; ++j) {
|
||||||
|
int icc = mInputCodes[i * MAX_PROXIMITY_CHARS_SIZE + j];
|
||||||
|
int icfjc = inputCodes[i * MAX_PROXIMITY_CHARS_SIZE + j];
|
||||||
|
icc+= 0;
|
||||||
|
icfjc += 0;
|
||||||
|
AKLOGI("--- (%d)%c,%c", i, icc, icfjc);
|
||||||
|
AKLOGI("--- A<%d>,B<%d>", icc, icfjc);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//Keep for debug, sorry
|
||||||
|
//for (int i = 0; i < MAX_WORD_LENGTH_INTERNAL * MAX_PROXIMITY_CHARS_SIZE; ++i) {
|
||||||
|
//if (i < inputLength * MAX_PROXIMITY_CHARS_SIZE) {
|
||||||
|
//mInputCodes[i] = mInputCodesFromJava[i];
|
||||||
|
//} else {
|
||||||
|
// mInputCodes[i] = 0;
|
||||||
|
// }
|
||||||
|
//}
|
||||||
mInputXCoordinates = xCoordinates;
|
mInputXCoordinates = xCoordinates;
|
||||||
mInputYCoordinates = yCoordinates;
|
mInputYCoordinates = yCoordinates;
|
||||||
mTouchPositionCorrectionEnabled =
|
mTouchPositionCorrectionEnabled =
|
||||||
|
@ -246,8 +281,9 @@ void ProximityInfo::setInputParams(const int* inputCodes, const int inputLength,
|
||||||
}
|
}
|
||||||
for (int j = 0; j < MAX_PROXIMITY_CHARS_SIZE && proximityChars[j] > 0; ++j) {
|
for (int j = 0; j < MAX_PROXIMITY_CHARS_SIZE && proximityChars[j] > 0; ++j) {
|
||||||
const int currentChar = proximityChars[j];
|
const int currentChar = proximityChars[j];
|
||||||
const int keyIndex = getKeyIndex(currentChar);
|
const float squaredDistance = hasInputCoordinates()
|
||||||
const float squaredDistance = calculateNormalizedSquaredDistance(keyIndex, i);
|
? calculateNormalizedSquaredDistance(getKeyIndex(currentChar), i)
|
||||||
|
: NOT_A_DISTANCE_FLOAT;
|
||||||
if (squaredDistance >= 0.0f) {
|
if (squaredDistance >= 0.0f) {
|
||||||
mNormalizedSquaredDistances[i * MAX_PROXIMITY_CHARS_SIZE + j] =
|
mNormalizedSquaredDistances[i * MAX_PROXIMITY_CHARS_SIZE + j] =
|
||||||
(int)(squaredDistance * NORMALIZED_SQUARED_DISTANCE_SCALING_FACTOR);
|
(int)(squaredDistance * NORMALIZED_SQUARED_DISTANCE_SCALING_FACTOR);
|
||||||
|
@ -267,7 +303,6 @@ inline float square(const float x) { return x * x; }
|
||||||
|
|
||||||
float ProximityInfo::calculateNormalizedSquaredDistance(
|
float ProximityInfo::calculateNormalizedSquaredDistance(
|
||||||
const int keyIndex, const int inputIndex) const {
|
const int keyIndex, const int inputIndex) const {
|
||||||
static const float NOT_A_DISTANCE_FLOAT = -1.0f;
|
|
||||||
if (keyIndex == NOT_A_INDEX) {
|
if (keyIndex == NOT_A_INDEX) {
|
||||||
return NOT_A_DISTANCE_FLOAT;
|
return NOT_A_DISTANCE_FLOAT;
|
||||||
}
|
}
|
||||||
|
@ -282,8 +317,12 @@ float ProximityInfo::calculateNormalizedSquaredDistance(
|
||||||
return squaredDistance / squaredRadius;
|
return squaredDistance / squaredRadius;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool ProximityInfo::hasInputCoordinates() const {
|
||||||
|
return mInputXCoordinates && mInputYCoordinates;
|
||||||
|
}
|
||||||
|
|
||||||
int ProximityInfo::getKeyIndex(const int c) const {
|
int ProximityInfo::getKeyIndex(const int c) const {
|
||||||
if (KEY_COUNT == 0 || !mInputXCoordinates || !mInputYCoordinates) {
|
if (KEY_COUNT == 0) {
|
||||||
// We do not have the coordinate data
|
// We do not have the coordinate data
|
||||||
return NOT_A_INDEX;
|
return NOT_A_INDEX;
|
||||||
}
|
}
|
||||||
|
|
|
@ -53,7 +53,7 @@ class ProximityInfo {
|
||||||
const float *sweetSpotCenterYs, const float *sweetSpotRadii);
|
const float *sweetSpotCenterYs, const float *sweetSpotRadii);
|
||||||
~ProximityInfo();
|
~ProximityInfo();
|
||||||
bool hasSpaceProximity(const int x, const int y) const;
|
bool hasSpaceProximity(const int x, const int y) const;
|
||||||
void setInputParams(const int *inputCodes, const int inputLength,
|
void setInputParams(const int32_t *inputCodes, const int inputLength,
|
||||||
const int *xCoordinates, const int *yCoordinates);
|
const int *xCoordinates, const int *yCoordinates);
|
||||||
const int* getProximityCharsAt(const int index) const;
|
const int* getProximityCharsAt(const int index) const;
|
||||||
unsigned short getPrimaryCharAt(const int index) const;
|
unsigned short getPrimaryCharAt(const int index) const;
|
||||||
|
@ -77,12 +77,15 @@ class ProximityInfo {
|
||||||
static const int MAX_KEY_COUNT_IN_A_KEYBOARD = 64;
|
static const int MAX_KEY_COUNT_IN_A_KEYBOARD = 64;
|
||||||
// The upper limit of the char code in mCodeToKeyIndex
|
// The upper limit of the char code in mCodeToKeyIndex
|
||||||
static const int MAX_CHAR_CODE = 127;
|
static const int MAX_CHAR_CODE = 127;
|
||||||
|
static const float NOT_A_DISTANCE_FLOAT = -1.0f;
|
||||||
|
static const int NOT_A_CODE = -1;
|
||||||
|
|
||||||
int getStartIndexFromCoordinates(const int x, const int y) const;
|
int getStartIndexFromCoordinates(const int x, const int y) const;
|
||||||
void initializeCodeToKeyIndex();
|
void initializeCodeToKeyIndex();
|
||||||
float calculateNormalizedSquaredDistance(const int keyIndex, const int inputIndex) const;
|
float calculateNormalizedSquaredDistance(const int keyIndex, const int inputIndex) const;
|
||||||
float calculateSquaredDistanceFromSweetSpotCenter(
|
float calculateSquaredDistanceFromSweetSpotCenter(
|
||||||
const int keyIndex, const int inputIndex) const;
|
const int keyIndex, const int inputIndex) const;
|
||||||
|
bool hasInputCoordinates() const;
|
||||||
int getKeyIndex(const int c) const;
|
int getKeyIndex(const int c) const;
|
||||||
bool hasSweetSpotData(const int keyIndex) const {
|
bool hasSweetSpotData(const int keyIndex) const {
|
||||||
// When there are no calibration data for a key,
|
// When there are no calibration data for a key,
|
||||||
|
@ -105,7 +108,9 @@ class ProximityInfo {
|
||||||
const int KEY_COUNT;
|
const int KEY_COUNT;
|
||||||
const bool HAS_TOUCH_POSITION_CORRECTION_DATA;
|
const bool HAS_TOUCH_POSITION_CORRECTION_DATA;
|
||||||
const std::string mLocaleStr;
|
const std::string mLocaleStr;
|
||||||
const int *mInputCodes;
|
// TODO: remove this
|
||||||
|
const int *mInputCodesFromJava;
|
||||||
|
int32_t *mInputCodes;
|
||||||
const int *mInputXCoordinates;
|
const int *mInputXCoordinates;
|
||||||
const int *mInputYCoordinates;
|
const int *mInputYCoordinates;
|
||||||
bool mTouchPositionCorrectionEnabled;
|
bool mTouchPositionCorrectionEnabled;
|
||||||
|
|
Loading…
Reference in a new issue