aboutsummaryrefslogtreecommitdiffstats
path: root/native/src/proximity_info.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'native/src/proximity_info.cpp')
-rw-r--r--native/src/proximity_info.cpp83
1 files changed, 54 insertions, 29 deletions
diff --git a/native/src/proximity_info.cpp b/native/src/proximity_info.cpp
index de3f421f3..20fa18a44 100644
--- a/native/src/proximity_info.cpp
+++ b/native/src/proximity_info.cpp
@@ -44,13 +44,21 @@ ProximityInfo::ProximityInfo(const int maxProximityCharsSize, const int keyboard
CELL_WIDTH((keyboardWidth + gridWidth - 1) / gridWidth),
CELL_HEIGHT((keyboardHeight + gridHeight - 1) / gridHeight),
KEY_COUNT(min(keyCount, MAX_KEY_COUNT_IN_A_KEYBOARD)),
- mInputXCoordinates(NULL), mInputYCoordinates(NULL) {
+ HAS_TOUCH_POSITION_CORRECTION_DATA(keyCount > 0 && keyXCoordinates && keyYCoordinates
+ && keyWidths && keyHeights && keyCharCodes && sweetSpotCenterXs
+ && sweetSpotCenterYs && sweetSpotRadii),
+ mInputXCoordinates(NULL), mInputYCoordinates(NULL),
+ mTouchPositionCorrectionEnabled(false) {
const int len = GRID_WIDTH * GRID_HEIGHT * MAX_PROXIMITY_CHARS_SIZE;
mProximityCharsArray = new uint32_t[len];
+ mNormalizedSquaredDistances = new int[len];
if (DEBUG_PROXIMITY_INFO) {
LOGI("Create proximity info array %d", len);
}
memcpy(mProximityCharsArray, proximityCharsArray, len * sizeof(mProximityCharsArray[0]));
+ for (int i = 0; i < len; ++i) {
+ mNormalizedSquaredDistances[i] = NOT_A_DISTANCE;
+ }
copyOrFillZero(mKeyXCoordinates, keyXCoordinates, KEY_COUNT * sizeof(mKeyXCoordinates[0]));
copyOrFillZero(mKeyYCoordinates, keyYCoordinates, KEY_COUNT * sizeof(mKeyYCoordinates[0]));
@@ -79,6 +87,7 @@ void ProximityInfo::initializeCodeToKeyIndex() {
}
ProximityInfo::~ProximityInfo() {
+ delete[] mNormalizedSquaredDistances;
delete[] mProximityCharsArray;
}
@@ -109,52 +118,61 @@ void ProximityInfo::setInputParams(const int* inputCodes, const int inputLength,
mInputCodes = inputCodes;
mInputXCoordinates = xCoordinates;
mInputYCoordinates = yCoordinates;
+ mTouchPositionCorrectionEnabled =
+ HAS_TOUCH_POSITION_CORRECTION_DATA && xCoordinates && yCoordinates;
mInputLength = inputLength;
for (int i = 0; i < inputLength; ++i) {
mPrimaryInputWord[i] = getPrimaryCharAt(i);
}
mPrimaryInputWord[inputLength] = 0;
for (int i = 0; i < mInputLength; ++i) {
- float normalizedSquaredDistance = calculateNormalizedSquaredDistance(i);
- if (normalizedSquaredDistance >= 0.0f) {
- mNormalizedSquaredDistance[i] =
- (int)(normalizedSquaredDistance * NORMALIZED_SQUARED_DISTANCE_SCALING_FACTOR);
- } else {
- mNormalizedSquaredDistance[i] = NOT_A_DISTANCE;
+ const int *proximityChars = getProximityCharsAt(i);
+ for (int j = 0; j < MAX_PROXIMITY_CHARS_SIZE && proximityChars[j] > 0; ++j) {
+ const int currentChar = proximityChars[j];
+ const int keyIndex = getKeyIndex(currentChar);
+ const float squaredDistance = calculateNormalizedSquaredDistance(keyIndex, i);
+ if (squaredDistance >= 0.0f) {
+ mNormalizedSquaredDistances[i * MAX_PROXIMITY_CHARS_SIZE + j] =
+ (int)(squaredDistance * NORMALIZED_SQUARED_DISTANCE_SCALING_FACTOR);
+ } else {
+ mNormalizedSquaredDistances[i * MAX_PROXIMITY_CHARS_SIZE + j] = (j == 0)
+ ? EQUIVALENT_CHAR_WITHOUT_DISTANCE_INFO
+ : PROXIMITY_CHAR_WITHOUT_DISTANCE_INFO;
+ }
}
}
}
inline float square(const float x) { return x * x; }
-float ProximityInfo::calculateNormalizedSquaredDistance(int index) const {
+float ProximityInfo::calculateNormalizedSquaredDistance(
+ const int keyIndex, const int inputIndex) const {
static const float NOT_A_DISTANCE_FLOAT = -1.0f;
- if (KEY_COUNT == 0 || !mInputXCoordinates || !mInputYCoordinates) {
- // We do not have the coordinate data
+ if (keyIndex == NOT_A_INDEX) {
return NOT_A_DISTANCE_FLOAT;
}
- const int currentChar = getPrimaryCharAt(index);
- const unsigned short baseLowerC = Dictionary::toBaseLowerCase(currentChar);
- if (baseLowerC > MAX_CHAR_CODE) {
+ if (!hasSweetSpotData(keyIndex)) {
return NOT_A_DISTANCE_FLOAT;
}
- const int keyIndex = mCodeToKeyIndex[baseLowerC];
- if (keyIndex < 0) {
- return NOT_A_DISTANCE_FLOAT;
+ const float squaredDistance = calculateSquaredDistanceFromSweetSpotCenter(keyIndex, inputIndex);
+ const float squaredRadius = square(mSweetSpotRadii[keyIndex]);
+ return squaredDistance / squaredRadius;
+}
+
+int ProximityInfo::getKeyIndex(const int c) const {
+ if (KEY_COUNT == 0 || !mInputXCoordinates || !mInputYCoordinates) {
+ // We do not have the coordinate data
+ return NOT_A_INDEX;
}
- const float radius = mSweetSpotRadii[keyIndex];
- if (radius <= 0.0) {
- // When there are no calibration data for a key,
- // the radius of the key is assigned to zero.
- return NOT_A_DISTANCE;
+ const unsigned short baseLowerC = Dictionary::toBaseLowerCase(c);
+ if (baseLowerC > MAX_CHAR_CODE) {
+ return NOT_A_INDEX;
}
- const float squaredRadius = square(radius);
- const float squaredDistance = calculateSquaredDistanceFromSweetSpotCenter(keyIndex, index);
- return squaredDistance / squaredRadius;
+ return mCodeToKeyIndex[baseLowerC];
}
float ProximityInfo::calculateSquaredDistanceFromSweetSpotCenter(
- int keyIndex, int inputIndex) const {
+ const int keyIndex, const int inputIndex) const {
const float sweetSpotCenterX = mSweetSpotCenterXs[keyIndex];
const float sweetSpotCenterY = mSweetSpotCenterYs[keyIndex];
const float inputX = (float)mInputXCoordinates[inputIndex];
@@ -202,11 +220,13 @@ bool ProximityInfo::existsAdjacentProximityChars(const int index) const {
// then the word contains at that position a character close to what the user
// typed.
// What the user typed is actually the first character of the array.
+// proximityIndex is a pointer to the variable where getMatchedProximityId returns
+// the index of c in the proximity chars of the input index.
// Notice : accented characters do not have a proximity list, so they are alone
// in their list. The non-accented version of the character should be considered
// "close", but not the other keys close to the non-accented version.
-ProximityInfo::ProximityType ProximityInfo::getMatchedProximityId(
- const int index, const unsigned short c, const bool checkProximityChars) const {
+ProximityInfo::ProximityType ProximityInfo::getMatchedProximityId(const int index,
+ const unsigned short c, const bool checkProximityChars, int *proximityIndex) const {
const int *currentChars = getProximityCharsAt(index);
const int firstChar = currentChars[0];
const unsigned short baseLowerC = Dictionary::toBaseLowerCase(c);
@@ -227,9 +247,14 @@ ProximityInfo::ProximityType ProximityInfo::getMatchedProximityId(
// Not an exact nor an accent-alike match: search the list of close keys
int j = 1;
- while (currentChars[j] > 0 && j < MAX_PROXIMITY_CHARS_SIZE) {
+ while (j < MAX_PROXIMITY_CHARS_SIZE && currentChars[j] > 0) {
const bool matched = (currentChars[j] == baseLowerC || currentChars[j] == c);
- if (matched) return NEAR_PROXIMITY_CHAR;
+ if (matched) {
+ if (proximityIndex) {
+ *proximityIndex = j;
+ }
+ return NEAR_PROXIMITY_CHAR;
+ }
++j;
}