diff options
Diffstat (limited to 'native/src/proximity_info.cpp')
-rw-r--r-- | native/src/proximity_info.cpp | 83 |
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; } |