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