proximity_info_state.cpp revision 4a3db7057f77dc85311fb1f94934b5a004ab613e
13e8c58f68d53e6cc9dbf59201c7bdfb8ad04a1cdSatoshi Kataoka/*
23e8c58f68d53e6cc9dbf59201c7bdfb8ad04a1cdSatoshi Kataoka * Copyright (C) 2012 The Android Open Source Project
33e8c58f68d53e6cc9dbf59201c7bdfb8ad04a1cdSatoshi Kataoka *
43e8c58f68d53e6cc9dbf59201c7bdfb8ad04a1cdSatoshi Kataoka * Licensed under the Apache License, Version 2.0 (the "License");
53e8c58f68d53e6cc9dbf59201c7bdfb8ad04a1cdSatoshi Kataoka * you may not use this file except in compliance with the License.
63e8c58f68d53e6cc9dbf59201c7bdfb8ad04a1cdSatoshi Kataoka * You may obtain a copy of the License at
73e8c58f68d53e6cc9dbf59201c7bdfb8ad04a1cdSatoshi Kataoka *
83e8c58f68d53e6cc9dbf59201c7bdfb8ad04a1cdSatoshi Kataoka *      http://www.apache.org/licenses/LICENSE-2.0
93e8c58f68d53e6cc9dbf59201c7bdfb8ad04a1cdSatoshi Kataoka *
103e8c58f68d53e6cc9dbf59201c7bdfb8ad04a1cdSatoshi Kataoka * Unless required by applicable law or agreed to in writing, software
113e8c58f68d53e6cc9dbf59201c7bdfb8ad04a1cdSatoshi Kataoka * distributed under the License is distributed on an "AS IS" BASIS,
123e8c58f68d53e6cc9dbf59201c7bdfb8ad04a1cdSatoshi Kataoka * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
133e8c58f68d53e6cc9dbf59201c7bdfb8ad04a1cdSatoshi Kataoka * See the License for the specific language governing permissions and
143e8c58f68d53e6cc9dbf59201c7bdfb8ad04a1cdSatoshi Kataoka * limitations under the License.
153e8c58f68d53e6cc9dbf59201c7bdfb8ad04a1cdSatoshi Kataoka */
163e8c58f68d53e6cc9dbf59201c7bdfb8ad04a1cdSatoshi Kataoka
173e8c58f68d53e6cc9dbf59201c7bdfb8ad04a1cdSatoshi Kataoka#include <assert.h>
183e8c58f68d53e6cc9dbf59201c7bdfb8ad04a1cdSatoshi Kataoka#include <stdint.h>
193e8c58f68d53e6cc9dbf59201c7bdfb8ad04a1cdSatoshi Kataoka#include <string>
203e8c58f68d53e6cc9dbf59201c7bdfb8ad04a1cdSatoshi Kataoka
213e8c58f68d53e6cc9dbf59201c7bdfb8ad04a1cdSatoshi Kataoka#define LOG_TAG "LatinIME: proximity_info_state.cpp"
223e8c58f68d53e6cc9dbf59201c7bdfb8ad04a1cdSatoshi Kataoka
233e8c58f68d53e6cc9dbf59201c7bdfb8ad04a1cdSatoshi Kataoka#include "additional_proximity_chars.h"
243e8c58f68d53e6cc9dbf59201c7bdfb8ad04a1cdSatoshi Kataoka#include "defines.h"
253e8c58f68d53e6cc9dbf59201c7bdfb8ad04a1cdSatoshi Kataoka#include "dictionary.h"
263e8c58f68d53e6cc9dbf59201c7bdfb8ad04a1cdSatoshi Kataoka#include "proximity_info.h"
273e8c58f68d53e6cc9dbf59201c7bdfb8ad04a1cdSatoshi Kataoka#include "proximity_info_state.h"
283e8c58f68d53e6cc9dbf59201c7bdfb8ad04a1cdSatoshi Kataoka
293e8c58f68d53e6cc9dbf59201c7bdfb8ad04a1cdSatoshi Kataokanamespace latinime {
304a3db7057f77dc85311fb1f94934b5a004ab613eSatoshi Kataokavoid ProximityInfoState::initInputParams(
314a3db7057f77dc85311fb1f94934b5a004ab613eSatoshi Kataoka        const ProximityInfo* proximityInfo, const int32_t* inputCodes, const int inputLength,
323e8c58f68d53e6cc9dbf59201c7bdfb8ad04a1cdSatoshi Kataoka        const int* xCoordinates, const int* yCoordinates) {
334a3db7057f77dc85311fb1f94934b5a004ab613eSatoshi Kataoka    mProximityInfo = proximityInfo;
344a3db7057f77dc85311fb1f94934b5a004ab613eSatoshi Kataoka    mHasTouchPositionCorrectionData = proximityInfo->hasTouchPositionCorrectionData();
354a3db7057f77dc85311fb1f94934b5a004ab613eSatoshi Kataoka    mMostCommonKeyWidthSquare = proximityInfo->getMostCommonKeyWidthSquare();
364a3db7057f77dc85311fb1f94934b5a004ab613eSatoshi Kataoka    mLocaleStr = proximityInfo->getLocaleStr();
374a3db7057f77dc85311fb1f94934b5a004ab613eSatoshi Kataoka    mKeyCount = proximityInfo->getKeyCount();
384a3db7057f77dc85311fb1f94934b5a004ab613eSatoshi Kataoka    mCellHeight = proximityInfo->getCellHeight();
394a3db7057f77dc85311fb1f94934b5a004ab613eSatoshi Kataoka    mCellWidth = proximityInfo->getCellWidth();
404a3db7057f77dc85311fb1f94934b5a004ab613eSatoshi Kataoka    mGridHeight = proximityInfo->getGridWidth();
414a3db7057f77dc85311fb1f94934b5a004ab613eSatoshi Kataoka    mGridWidth = proximityInfo->getGridHeight();
424a3db7057f77dc85311fb1f94934b5a004ab613eSatoshi Kataoka    const int normalizedSquaredDistancesLength =
434a3db7057f77dc85311fb1f94934b5a004ab613eSatoshi Kataoka            MAX_PROXIMITY_CHARS_SIZE_INTERNAL * MAX_WORD_LENGTH_INTERNAL;
444a3db7057f77dc85311fb1f94934b5a004ab613eSatoshi Kataoka    for (int i = 0; i < normalizedSquaredDistancesLength; ++i) {
454a3db7057f77dc85311fb1f94934b5a004ab613eSatoshi Kataoka        mNormalizedSquaredDistances[i] = NOT_A_DISTANCE;
464a3db7057f77dc85311fb1f94934b5a004ab613eSatoshi Kataoka    }
474a3db7057f77dc85311fb1f94934b5a004ab613eSatoshi Kataoka
483e8c58f68d53e6cc9dbf59201c7bdfb8ad04a1cdSatoshi Kataoka    memset(mInputCodes, 0,
494a3db7057f77dc85311fb1f94934b5a004ab613eSatoshi Kataoka            MAX_WORD_LENGTH_INTERNAL * MAX_PROXIMITY_CHARS_SIZE_INTERNAL * sizeof(mInputCodes[0]));
503e8c58f68d53e6cc9dbf59201c7bdfb8ad04a1cdSatoshi Kataoka
513e8c58f68d53e6cc9dbf59201c7bdfb8ad04a1cdSatoshi Kataoka    for (int i = 0; i < inputLength; ++i) {
523e8c58f68d53e6cc9dbf59201c7bdfb8ad04a1cdSatoshi Kataoka        const int32_t primaryKey = inputCodes[i];
533e8c58f68d53e6cc9dbf59201c7bdfb8ad04a1cdSatoshi Kataoka        const int x = xCoordinates[i];
543e8c58f68d53e6cc9dbf59201c7bdfb8ad04a1cdSatoshi Kataoka        const int y = yCoordinates[i];
554a3db7057f77dc85311fb1f94934b5a004ab613eSatoshi Kataoka        int *proximities = &mInputCodes[i * MAX_PROXIMITY_CHARS_SIZE_INTERNAL];
563e8c58f68d53e6cc9dbf59201c7bdfb8ad04a1cdSatoshi Kataoka        mProximityInfo->calculateNearbyKeyCodes(x, y, primaryKey, proximities);
573e8c58f68d53e6cc9dbf59201c7bdfb8ad04a1cdSatoshi Kataoka    }
583e8c58f68d53e6cc9dbf59201c7bdfb8ad04a1cdSatoshi Kataoka
593e8c58f68d53e6cc9dbf59201c7bdfb8ad04a1cdSatoshi Kataoka    if (DEBUG_PROXIMITY_CHARS) {
603e8c58f68d53e6cc9dbf59201c7bdfb8ad04a1cdSatoshi Kataoka        for (int i = 0; i < inputLength; ++i) {
613e8c58f68d53e6cc9dbf59201c7bdfb8ad04a1cdSatoshi Kataoka            AKLOGI("---");
624a3db7057f77dc85311fb1f94934b5a004ab613eSatoshi Kataoka            for (int j = 0; j < MAX_PROXIMITY_CHARS_SIZE_INTERNAL; ++j) {
634a3db7057f77dc85311fb1f94934b5a004ab613eSatoshi Kataoka                int icc = mInputCodes[i * MAX_PROXIMITY_CHARS_SIZE_INTERNAL + j];
644a3db7057f77dc85311fb1f94934b5a004ab613eSatoshi Kataoka                int icfjc = inputCodes[i * MAX_PROXIMITY_CHARS_SIZE_INTERNAL + j];
653e8c58f68d53e6cc9dbf59201c7bdfb8ad04a1cdSatoshi Kataoka                icc += 0;
663e8c58f68d53e6cc9dbf59201c7bdfb8ad04a1cdSatoshi Kataoka                icfjc += 0;
673e8c58f68d53e6cc9dbf59201c7bdfb8ad04a1cdSatoshi Kataoka                AKLOGI("--- (%d)%c,%c", i, icc, icfjc); AKLOGI("--- A<%d>,B<%d>", icc, icfjc);
683e8c58f68d53e6cc9dbf59201c7bdfb8ad04a1cdSatoshi Kataoka            }
693e8c58f68d53e6cc9dbf59201c7bdfb8ad04a1cdSatoshi Kataoka        }
703e8c58f68d53e6cc9dbf59201c7bdfb8ad04a1cdSatoshi Kataoka    }
713e8c58f68d53e6cc9dbf59201c7bdfb8ad04a1cdSatoshi Kataoka    mInputXCoordinates = xCoordinates;
723e8c58f68d53e6cc9dbf59201c7bdfb8ad04a1cdSatoshi Kataoka    mInputYCoordinates = yCoordinates;
734a3db7057f77dc85311fb1f94934b5a004ab613eSatoshi Kataoka    mTouchPositionCorrectionEnabled =
744a3db7057f77dc85311fb1f94934b5a004ab613eSatoshi Kataoka            mHasTouchPositionCorrectionData && xCoordinates && yCoordinates;
753e8c58f68d53e6cc9dbf59201c7bdfb8ad04a1cdSatoshi Kataoka    mInputLength = inputLength;
763e8c58f68d53e6cc9dbf59201c7bdfb8ad04a1cdSatoshi Kataoka    for (int i = 0; i < inputLength; ++i) {
773e8c58f68d53e6cc9dbf59201c7bdfb8ad04a1cdSatoshi Kataoka        mPrimaryInputWord[i] = getPrimaryCharAt(i);
783e8c58f68d53e6cc9dbf59201c7bdfb8ad04a1cdSatoshi Kataoka    }
793e8c58f68d53e6cc9dbf59201c7bdfb8ad04a1cdSatoshi Kataoka    mPrimaryInputWord[inputLength] = 0;
803e8c58f68d53e6cc9dbf59201c7bdfb8ad04a1cdSatoshi Kataoka    if (DEBUG_PROXIMITY_CHARS) {
813e8c58f68d53e6cc9dbf59201c7bdfb8ad04a1cdSatoshi Kataoka        AKLOGI("--- initInputParams");
823e8c58f68d53e6cc9dbf59201c7bdfb8ad04a1cdSatoshi Kataoka    }
833e8c58f68d53e6cc9dbf59201c7bdfb8ad04a1cdSatoshi Kataoka    for (int i = 0; i < mInputLength; ++i) {
843e8c58f68d53e6cc9dbf59201c7bdfb8ad04a1cdSatoshi Kataoka        const int *proximityChars = getProximityCharsAt(i);
853e8c58f68d53e6cc9dbf59201c7bdfb8ad04a1cdSatoshi Kataoka        const int primaryKey = proximityChars[0];
863e8c58f68d53e6cc9dbf59201c7bdfb8ad04a1cdSatoshi Kataoka        const int x = xCoordinates[i];
873e8c58f68d53e6cc9dbf59201c7bdfb8ad04a1cdSatoshi Kataoka        const int y = yCoordinates[i];
883e8c58f68d53e6cc9dbf59201c7bdfb8ad04a1cdSatoshi Kataoka        if (DEBUG_PROXIMITY_CHARS) {
893e8c58f68d53e6cc9dbf59201c7bdfb8ad04a1cdSatoshi Kataoka            int a = x + y + primaryKey;
903e8c58f68d53e6cc9dbf59201c7bdfb8ad04a1cdSatoshi Kataoka            a += 0;
913e8c58f68d53e6cc9dbf59201c7bdfb8ad04a1cdSatoshi Kataoka            AKLOGI("--- Primary = %c, x = %d, y = %d", primaryKey, x, y);
923e8c58f68d53e6cc9dbf59201c7bdfb8ad04a1cdSatoshi Kataoka        }
934a3db7057f77dc85311fb1f94934b5a004ab613eSatoshi Kataoka        for (int j = 0; j < MAX_PROXIMITY_CHARS_SIZE_INTERNAL && proximityChars[j] > 0; ++j) {
943e8c58f68d53e6cc9dbf59201c7bdfb8ad04a1cdSatoshi Kataoka            const int currentChar = proximityChars[j];
953e8c58f68d53e6cc9dbf59201c7bdfb8ad04a1cdSatoshi Kataoka            const float squaredDistance =
963e8c58f68d53e6cc9dbf59201c7bdfb8ad04a1cdSatoshi Kataoka                    hasInputCoordinates() ? calculateNormalizedSquaredDistance(
973e8c58f68d53e6cc9dbf59201c7bdfb8ad04a1cdSatoshi Kataoka                            mProximityInfo->getKeyIndex(currentChar), i) :
983e8c58f68d53e6cc9dbf59201c7bdfb8ad04a1cdSatoshi Kataoka                            NOT_A_DISTANCE_FLOAT;
993e8c58f68d53e6cc9dbf59201c7bdfb8ad04a1cdSatoshi Kataoka            if (squaredDistance >= 0.0f) {
1004a3db7057f77dc85311fb1f94934b5a004ab613eSatoshi Kataoka                mNormalizedSquaredDistances[i * MAX_PROXIMITY_CHARS_SIZE_INTERNAL + j] =
1013e8c58f68d53e6cc9dbf59201c7bdfb8ad04a1cdSatoshi Kataoka                        (int) (squaredDistance * NORMALIZED_SQUARED_DISTANCE_SCALING_FACTOR);
1023e8c58f68d53e6cc9dbf59201c7bdfb8ad04a1cdSatoshi Kataoka            } else {
1034a3db7057f77dc85311fb1f94934b5a004ab613eSatoshi Kataoka                mNormalizedSquaredDistances[i * MAX_PROXIMITY_CHARS_SIZE_INTERNAL + j] =
1043e8c58f68d53e6cc9dbf59201c7bdfb8ad04a1cdSatoshi Kataoka                        (j == 0) ? EQUIVALENT_CHAR_WITHOUT_DISTANCE_INFO :
1053e8c58f68d53e6cc9dbf59201c7bdfb8ad04a1cdSatoshi Kataoka                                PROXIMITY_CHAR_WITHOUT_DISTANCE_INFO;
1063e8c58f68d53e6cc9dbf59201c7bdfb8ad04a1cdSatoshi Kataoka            }
1073e8c58f68d53e6cc9dbf59201c7bdfb8ad04a1cdSatoshi Kataoka            if (DEBUG_PROXIMITY_CHARS) {
1083e8c58f68d53e6cc9dbf59201c7bdfb8ad04a1cdSatoshi Kataoka                AKLOGI("--- Proximity (%d) = %c", j, currentChar);
1093e8c58f68d53e6cc9dbf59201c7bdfb8ad04a1cdSatoshi Kataoka            }
1103e8c58f68d53e6cc9dbf59201c7bdfb8ad04a1cdSatoshi Kataoka        }
1113e8c58f68d53e6cc9dbf59201c7bdfb8ad04a1cdSatoshi Kataoka    }
1123e8c58f68d53e6cc9dbf59201c7bdfb8ad04a1cdSatoshi Kataoka}
1134a3db7057f77dc85311fb1f94934b5a004ab613eSatoshi Kataoka
1144a3db7057f77dc85311fb1f94934b5a004ab613eSatoshi Kataokafloat ProximityInfoState::calculateNormalizedSquaredDistance(
1154a3db7057f77dc85311fb1f94934b5a004ab613eSatoshi Kataoka        const int keyIndex, const int inputIndex) const {
1164a3db7057f77dc85311fb1f94934b5a004ab613eSatoshi Kataoka    if (keyIndex == NOT_AN_INDEX) {
1174a3db7057f77dc85311fb1f94934b5a004ab613eSatoshi Kataoka        return NOT_A_DISTANCE_FLOAT;
1184a3db7057f77dc85311fb1f94934b5a004ab613eSatoshi Kataoka    }
1194a3db7057f77dc85311fb1f94934b5a004ab613eSatoshi Kataoka    if (!mProximityInfo->hasSweetSpotData(keyIndex)) {
1204a3db7057f77dc85311fb1f94934b5a004ab613eSatoshi Kataoka        return NOT_A_DISTANCE_FLOAT;
1214a3db7057f77dc85311fb1f94934b5a004ab613eSatoshi Kataoka    }
1224a3db7057f77dc85311fb1f94934b5a004ab613eSatoshi Kataoka    if (NOT_A_COORDINATE == mInputXCoordinates[inputIndex]) {
1234a3db7057f77dc85311fb1f94934b5a004ab613eSatoshi Kataoka        return NOT_A_DISTANCE_FLOAT;
1244a3db7057f77dc85311fb1f94934b5a004ab613eSatoshi Kataoka    }
1254a3db7057f77dc85311fb1f94934b5a004ab613eSatoshi Kataoka    const float squaredDistance = calculateSquaredDistanceFromSweetSpotCenter(
1264a3db7057f77dc85311fb1f94934b5a004ab613eSatoshi Kataoka            keyIndex, inputIndex);
1274a3db7057f77dc85311fb1f94934b5a004ab613eSatoshi Kataoka    const float squaredRadius = square(mProximityInfo->getSweetSpotRadiiAt(keyIndex));
1284a3db7057f77dc85311fb1f94934b5a004ab613eSatoshi Kataoka    return squaredDistance / squaredRadius;
1294a3db7057f77dc85311fb1f94934b5a004ab613eSatoshi Kataoka}
1304a3db7057f77dc85311fb1f94934b5a004ab613eSatoshi Kataoka
1314a3db7057f77dc85311fb1f94934b5a004ab613eSatoshi Kataokafloat ProximityInfoState::calculateSquaredDistanceFromSweetSpotCenter(
1324a3db7057f77dc85311fb1f94934b5a004ab613eSatoshi Kataoka        const int keyIndex, const int inputIndex) const {
1334a3db7057f77dc85311fb1f94934b5a004ab613eSatoshi Kataoka    const float sweetSpotCenterX = mProximityInfo->getSweetSpotCenterXAt(keyIndex);
1344a3db7057f77dc85311fb1f94934b5a004ab613eSatoshi Kataoka    const float sweetSpotCenterY = mProximityInfo->getSweetSpotCenterYAt(keyIndex);
1354a3db7057f77dc85311fb1f94934b5a004ab613eSatoshi Kataoka    const float inputX = (float)mInputXCoordinates[inputIndex];
1364a3db7057f77dc85311fb1f94934b5a004ab613eSatoshi Kataoka    const float inputY = (float)mInputYCoordinates[inputIndex];
1374a3db7057f77dc85311fb1f94934b5a004ab613eSatoshi Kataoka    return square(inputX - sweetSpotCenterX) + square(inputY - sweetSpotCenterY);
1384a3db7057f77dc85311fb1f94934b5a004ab613eSatoshi Kataoka}
1393e8c58f68d53e6cc9dbf59201c7bdfb8ad04a1cdSatoshi Kataoka} // namespace latinime
140