proximity_info_state.cpp revision e5aad5646309e80e1cd71533fb47a6be43f3aa2f
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 1777e8e81ad95cfc1eb8f8407fc872674b8d08bbe9Ken Wakasa#include <cstring> // for memset() 18806eba452423e5e5971ef096dfae3fed180db665Keisuke Kuroyanagi#include <sstream> // for debug prints 193e8c58f68d53e6cc9dbf59201c7bdfb8ad04a1cdSatoshi Kataoka 203e8c58f68d53e6cc9dbf59201c7bdfb8ad04a1cdSatoshi Kataoka#define LOG_TAG "LatinIME: proximity_info_state.cpp" 213e8c58f68d53e6cc9dbf59201c7bdfb8ad04a1cdSatoshi Kataoka 223e8c58f68d53e6cc9dbf59201c7bdfb8ad04a1cdSatoshi Kataoka#include "defines.h" 236cee61deebd0ca2b85054ccc239523d1e5fdfab1Ken Wakasa#include "geometry_utils.h" 243e8c58f68d53e6cc9dbf59201c7bdfb8ad04a1cdSatoshi Kataoka#include "proximity_info.h" 253e8c58f68d53e6cc9dbf59201c7bdfb8ad04a1cdSatoshi Kataoka#include "proximity_info_state.h" 2647cc52415e3affb83eb4369190425b2a17b956c5Satoshi Kataoka#include "proximity_info_state_utils.h" 273e8c58f68d53e6cc9dbf59201c7bdfb8ad04a1cdSatoshi Kataoka 283e8c58f68d53e6cc9dbf59201c7bdfb8ad04a1cdSatoshi Kataokanamespace latinime { 29764dd712032d7b8012797b1116b523bef7b907f3Ken Wakasa 30764dd712032d7b8012797b1116b523bef7b907f3Ken Wakasaconst int ProximityInfoState::NOT_A_CODE = -1; 31764dd712032d7b8012797b1116b523bef7b907f3Ken Wakasa 32233aad5e5c7567a97af30f38f50a65365f729dfeSatoshi Kataokavoid ProximityInfoState::initInputParams(const int pointerId, const float maxPointToKeyLength, 331e61493c50082264caaef862df02b1ccc84dc396Ken Wakasa const ProximityInfo *proximityInfo, const int *const inputCodes, const int inputSize, 34687a244703a02323ebd64433cbaead5def499861Satoshi Kataoka const int *const xCoordinates, const int *const yCoordinates, const int *const times, 35687a244703a02323ebd64433cbaead5def499861Satoshi Kataoka const int *const pointerIds, const bool isGeometric) { 36fe4f1ce26ca41ef51b5245d70e93b502f76262a5Satoshi Kataoka mIsContinuationPossible = checkAndReturnIsContinuationPossible( 37fe4f1ce26ca41ef51b5245d70e93b502f76262a5Satoshi Kataoka inputSize, xCoordinates, yCoordinates, times, isGeometric); 38096f35ff4b5413906e2a339663baf16e5dabaf64Keisuke Kuroyanagi 394a3db7057f77dc85311fb1f94934b5a004ab613eSatoshi Kataoka mProximityInfo = proximityInfo; 404a3db7057f77dc85311fb1f94934b5a004ab613eSatoshi Kataoka mHasTouchPositionCorrectionData = proximityInfo->hasTouchPositionCorrectionData(); 414a3db7057f77dc85311fb1f94934b5a004ab613eSatoshi Kataoka mMostCommonKeyWidthSquare = proximityInfo->getMostCommonKeyWidthSquare(); 424a3db7057f77dc85311fb1f94934b5a004ab613eSatoshi Kataoka mKeyCount = proximityInfo->getKeyCount(); 434a3db7057f77dc85311fb1f94934b5a004ab613eSatoshi Kataoka mCellHeight = proximityInfo->getCellHeight(); 444a3db7057f77dc85311fb1f94934b5a004ab613eSatoshi Kataoka mCellWidth = proximityInfo->getCellWidth(); 454a3db7057f77dc85311fb1f94934b5a004ab613eSatoshi Kataoka mGridHeight = proximityInfo->getGridWidth(); 464a3db7057f77dc85311fb1f94934b5a004ab613eSatoshi Kataoka mGridWidth = proximityInfo->getGridHeight(); 473e8c58f68d53e6cc9dbf59201c7bdfb8ad04a1cdSatoshi Kataoka 48bf78e1371c12d819020d60f0e585f5e6c26e6aa2Satoshi Kataoka memset(mInputProximities, 0, sizeof(mInputProximities)); 493e8c58f68d53e6cc9dbf59201c7bdfb8ad04a1cdSatoshi Kataoka 5008f00cf55f2e083c1ed254a32495b622c9ad9862Satoshi Kataoka if (!isGeometric && pointerId == 0) { 51bf78e1371c12d819020d60f0e585f5e6c26e6aa2Satoshi Kataoka mProximityInfo->initializeProximities(inputCodes, xCoordinates, yCoordinates, 52bf78e1371c12d819020d60f0e585f5e6c26e6aa2Satoshi Kataoka inputSize, mInputProximities); 533e8c58f68d53e6cc9dbf59201c7bdfb8ad04a1cdSatoshi Kataoka } 54687a244703a02323ebd64433cbaead5def499861Satoshi Kataoka 55687a244703a02323ebd64433cbaead5def499861Satoshi Kataoka /////////////////////// 56687a244703a02323ebd64433cbaead5def499861Satoshi Kataoka // Setup touch points 57096f35ff4b5413906e2a339663baf16e5dabaf64Keisuke Kuroyanagi int pushTouchPointStartIndex = 0; 58096f35ff4b5413906e2a339663baf16e5dabaf64Keisuke Kuroyanagi int lastSavedInputSize = 0; 5908f00cf55f2e083c1ed254a32495b622c9ad9862Satoshi Kataoka mMaxPointToKeyLength = maxPointToKeyLength; 60d7a8fbf6a9ec8828d4b6d1c615a6c605bbe5b72eSatoshi Kataoka if (mIsContinuationPossible && mSampledInputIndice.size() > 1) { 61096f35ff4b5413906e2a339663baf16e5dabaf64Keisuke Kuroyanagi // Just update difference. 62096f35ff4b5413906e2a339663baf16e5dabaf64Keisuke Kuroyanagi // Two points prior is never skipped. Thus, we pop 2 input point data here. 63d7a8fbf6a9ec8828d4b6d1c615a6c605bbe5b72eSatoshi Kataoka pushTouchPointStartIndex = mSampledInputIndice[mSampledInputIndice.size() - 2]; 64096f35ff4b5413906e2a339663baf16e5dabaf64Keisuke Kuroyanagi popInputData(); 65096f35ff4b5413906e2a339663baf16e5dabaf64Keisuke Kuroyanagi popInputData(); 66feec20a692c9ffdecf7855a45531a12f129086caSatoshi Kataoka lastSavedInputSize = mSampledInputXs.size(); 67096f35ff4b5413906e2a339663baf16e5dabaf64Keisuke Kuroyanagi } else { 68096f35ff4b5413906e2a339663baf16e5dabaf64Keisuke Kuroyanagi // Clear all data. 69feec20a692c9ffdecf7855a45531a12f129086caSatoshi Kataoka mSampledInputXs.clear(); 70feec20a692c9ffdecf7855a45531a12f129086caSatoshi Kataoka mSampledInputYs.clear(); 71d7a8fbf6a9ec8828d4b6d1c615a6c605bbe5b72eSatoshi Kataoka mSampledTimes.clear(); 72d7a8fbf6a9ec8828d4b6d1c615a6c605bbe5b72eSatoshi Kataoka mSampledInputIndice.clear(); 73d7a8fbf6a9ec8828d4b6d1c615a6c605bbe5b72eSatoshi Kataoka mSampledLengthCache.clear(); 74e5aad5646309e80e1cd71533fb47a6be43f3aa2fSatoshi Kataoka mSampledDistanceCache_G.clear(); 75e5aad5646309e80e1cd71533fb47a6be43f3aa2fSatoshi Kataoka mSampledNearKeysVector.clear(); 76e5aad5646309e80e1cd71533fb47a6be43f3aa2fSatoshi Kataoka mSampledSearchKeysVector.clear(); 779af533538ea749d7c930bb3125fa4d3e4feb8478Satoshi Kataoka mSpeedRates.clear(); 786ae8dd4343445d2df4444388b605d2aa930fa2a0Satoshi Kataoka mBeelineSpeedPercentiles.clear(); 79806eba452423e5e5971ef096dfae3fed180db665Keisuke Kuroyanagi mCharProbabilities.clear(); 801e06a4d8e9e71188ed685282155ea52a48ddc050Keisuke Kuroyanagi mDirections.clear(); 81096f35ff4b5413906e2a339663baf16e5dabaf64Keisuke Kuroyanagi } 829182daf98c0d1db897e82b77c2196b7f9aad6f01Satoshi Kataoka if (DEBUG_GEO_FULL) { 839182daf98c0d1db897e82b77c2196b7f9aad6f01Satoshi Kataoka AKLOGI("Init ProximityInfoState: reused points = %d, last input size = %d", 849182daf98c0d1db897e82b77c2196b7f9aad6f01Satoshi Kataoka pushTouchPointStartIndex, lastSavedInputSize); 859182daf98c0d1db897e82b77c2196b7f9aad6f01Satoshi Kataoka } 86feec20a692c9ffdecf7855a45531a12f129086caSatoshi Kataoka mSampledInputSize = 0; 87d9c10b19793b011f862e3dd31883f746044431d7Keisuke Kuroyanagi 88687a244703a02323ebd64433cbaead5def499861Satoshi Kataoka if (xCoordinates && yCoordinates) { 8947cc52415e3affb83eb4369190425b2a17b956c5Satoshi Kataoka mSampledInputSize = ProximityInfoStateUtils::updateTouchPoints( 9047cc52415e3affb83eb4369190425b2a17b956c5Satoshi Kataoka mProximityInfo->getMostCommonKeyWidth(), mProximityInfo, mMaxPointToKeyLength, 9147cc52415e3affb83eb4369190425b2a17b956c5Satoshi Kataoka mInputProximities, xCoordinates, yCoordinates, times, pointerIds, inputSize, 92d7a8fbf6a9ec8828d4b6d1c615a6c605bbe5b72eSatoshi Kataoka isGeometric, pointerId, pushTouchPointStartIndex, &mSampledInputXs, 93d7a8fbf6a9ec8828d4b6d1c615a6c605bbe5b72eSatoshi Kataoka &mSampledInputYs, &mSampledTimes, &mSampledLengthCache, &mSampledInputIndice); 943e8c58f68d53e6cc9dbf59201c7bdfb8ad04a1cdSatoshi Kataoka } 95687a244703a02323ebd64433cbaead5def499861Satoshi Kataoka 96feec20a692c9ffdecf7855a45531a12f129086caSatoshi Kataoka if (mSampledInputSize > 0 && isGeometric) { 97ee62b78c9675bddaf2437e0cf521f6115e1d9febSatoshi Kataoka mAverageSpeed = ProximityInfoStateUtils::refreshSpeedRates( 98ee62b78c9675bddaf2437e0cf521f6115e1d9febSatoshi Kataoka inputSize, xCoordinates, yCoordinates, times, lastSavedInputSize, 99d7a8fbf6a9ec8828d4b6d1c615a6c605bbe5b72eSatoshi Kataoka mSampledInputSize, &mSampledInputXs, &mSampledInputYs, &mSampledTimes, 100d7a8fbf6a9ec8828d4b6d1c615a6c605bbe5b72eSatoshi Kataoka &mSampledLengthCache, &mSampledInputIndice, &mSpeedRates, &mDirections); 101ee62b78c9675bddaf2437e0cf521f6115e1d9febSatoshi Kataoka ProximityInfoStateUtils::refreshBeelineSpeedRates( 102ee62b78c9675bddaf2437e0cf521f6115e1d9febSatoshi Kataoka mProximityInfo->getMostCommonKeyWidth(), mAverageSpeed, inputSize, 103ee62b78c9675bddaf2437e0cf521f6115e1d9febSatoshi Kataoka xCoordinates, yCoordinates, times, mSampledInputSize, &mSampledInputXs, 104d7a8fbf6a9ec8828d4b6d1c615a6c605bbe5b72eSatoshi Kataoka &mSampledInputYs, &mSampledInputIndice, &mBeelineSpeedPercentiles); 105ff74cc3e5e75fc0c6b9ffaa5e68d879775dc6115Keisuke Kuroyanagi } 106ff74cc3e5e75fc0c6b9ffaa5e68d879775dc6115Keisuke Kuroyanagi 107feec20a692c9ffdecf7855a45531a12f129086caSatoshi Kataoka if (mSampledInputSize > 0) { 108d7a8fbf6a9ec8828d4b6d1c615a6c605bbe5b72eSatoshi Kataoka ProximityInfoStateUtils::initGeometricDistanceInfos( 109d7a8fbf6a9ec8828d4b6d1c615a6c605bbe5b72eSatoshi Kataoka mProximityInfo, mProximityInfo->getKeyCount(), 110d7a8fbf6a9ec8828d4b6d1c615a6c605bbe5b72eSatoshi Kataoka mSampledInputSize, lastSavedInputSize, &mSampledInputXs, &mSampledInputYs, 111e5aad5646309e80e1cd71533fb47a6be43f3aa2fSatoshi Kataoka &mSampledNearKeysVector, &mSampledDistanceCache_G); 112ff74cc3e5e75fc0c6b9ffaa5e68d879775dc6115Keisuke Kuroyanagi if (isGeometric) { 113ff74cc3e5e75fc0c6b9ffaa5e68d879775dc6115Keisuke Kuroyanagi // updates probabilities of skipping or mapping each key for all points. 114d4828d5053ac30476b884c177235be0cac982c92Satoshi Kataoka ProximityInfoStateUtils::updateAlignPointProbabilities( 115d4828d5053ac30476b884c177235be0cac982c92Satoshi Kataoka mMaxPointToKeyLength, mProximityInfo->getMostCommonKeyWidth(), 116d7a8fbf6a9ec8828d4b6d1c615a6c605bbe5b72eSatoshi Kataoka mProximityInfo->getKeyCount(), lastSavedInputSize, mSampledInputSize, 117d7a8fbf6a9ec8828d4b6d1c615a6c605bbe5b72eSatoshi Kataoka &mSampledInputXs, &mSampledInputYs, &mSpeedRates, &mSampledLengthCache, 118e5aad5646309e80e1cd71533fb47a6be43f3aa2fSatoshi Kataoka &mSampledDistanceCache_G, &mSampledNearKeysVector, &mCharProbabilities); 119e5aad5646309e80e1cd71533fb47a6be43f3aa2fSatoshi Kataoka ProximityInfoStateUtils::updateSampledSearchKeysVector(mProximityInfo, 120e5aad5646309e80e1cd71533fb47a6be43f3aa2fSatoshi Kataoka mSampledInputSize, lastSavedInputSize, &mSampledLengthCache, 121e5aad5646309e80e1cd71533fb47a6be43f3aa2fSatoshi Kataoka &mSampledNearKeysVector, &mSampledSearchKeysVector); 122687a244703a02323ebd64433cbaead5def499861Satoshi Kataoka } 123687a244703a02323ebd64433cbaead5def499861Satoshi Kataoka } 12408f00cf55f2e083c1ed254a32495b622c9ad9862Satoshi Kataoka 125806eba452423e5e5971ef096dfae3fed180db665Keisuke Kuroyanagi if (DEBUG_SAMPLING_POINTS) { 126d7a8fbf6a9ec8828d4b6d1c615a6c605bbe5b72eSatoshi Kataoka ProximityInfoStateUtils::dump(isGeometric, inputSize, xCoordinates, yCoordinates, 127e2912d17e4dab75b81f4c9e41a539e491ac059caSatoshi Kataoka mSampledInputSize, &mSampledInputXs, &mSampledInputYs, &mSampledTimes, &mSpeedRates, 128d7a8fbf6a9ec8828d4b6d1c615a6c605bbe5b72eSatoshi Kataoka &mBeelineSpeedPercentiles); 129806eba452423e5e5971ef096dfae3fed180db665Keisuke Kuroyanagi } 130687a244703a02323ebd64433cbaead5def499861Satoshi Kataoka // end 131687a244703a02323ebd64433cbaead5def499861Satoshi Kataoka /////////////////////// 132687a244703a02323ebd64433cbaead5def499861Satoshi Kataoka 13308f00cf55f2e083c1ed254a32495b622c9ad9862Satoshi Kataoka memset(mNormalizedSquaredDistances, NOT_A_DISTANCE, sizeof(mNormalizedSquaredDistances)); 13408f00cf55f2e083c1ed254a32495b622c9ad9862Satoshi Kataoka memset(mPrimaryInputWord, 0, sizeof(mPrimaryInputWord)); 135feec20a692c9ffdecf7855a45531a12f129086caSatoshi Kataoka mTouchPositionCorrectionEnabled = mSampledInputSize > 0 && mHasTouchPositionCorrectionData 1360edab9d2fcc30667c79aa9221dbb27f042d8b455Satoshi Kataoka && xCoordinates && yCoordinates; 13708f00cf55f2e083c1ed254a32495b622c9ad9862Satoshi Kataoka if (!isGeometric && pointerId == 0) { 138d7a8fbf6a9ec8828d4b6d1c615a6c605bbe5b72eSatoshi Kataoka ProximityInfoStateUtils::initPrimaryInputWord( 139d7a8fbf6a9ec8828d4b6d1c615a6c605bbe5b72eSatoshi Kataoka inputSize, mInputProximities, mPrimaryInputWord); 140d7a8fbf6a9ec8828d4b6d1c615a6c605bbe5b72eSatoshi Kataoka if (mTouchPositionCorrectionEnabled) { 141d7a8fbf6a9ec8828d4b6d1c615a6c605bbe5b72eSatoshi Kataoka ProximityInfoStateUtils::initNormalizedSquaredDistances( 142d7a8fbf6a9ec8828d4b6d1c615a6c605bbe5b72eSatoshi Kataoka mProximityInfo, inputSize, xCoordinates, yCoordinates, mInputProximities, 143d7a8fbf6a9ec8828d4b6d1c615a6c605bbe5b72eSatoshi Kataoka hasInputCoordinates(), &mSampledInputXs, &mSampledInputYs, 144d7a8fbf6a9ec8828d4b6d1c615a6c605bbe5b72eSatoshi Kataoka mNormalizedSquaredDistances); 1453e8c58f68d53e6cc9dbf59201c7bdfb8ad04a1cdSatoshi Kataoka } 1463e8c58f68d53e6cc9dbf59201c7bdfb8ad04a1cdSatoshi Kataoka } 147952ec4977d772607140773ae7d8868f86a7e0097Satoshi Kataoka if (DEBUG_GEO_FULL) { 148feec20a692c9ffdecf7855a45531a12f129086caSatoshi Kataoka AKLOGI("ProximityState init finished: %d points out of %d", mSampledInputSize, inputSize); 149feec20a692c9ffdecf7855a45531a12f129086caSatoshi Kataoka } 150feec20a692c9ffdecf7855a45531a12f129086caSatoshi Kataoka} 151feec20a692c9ffdecf7855a45531a12f129086caSatoshi Kataoka 152096f35ff4b5413906e2a339663baf16e5dabaf64Keisuke Kuroyanagibool ProximityInfoState::checkAndReturnIsContinuationPossible(const int inputSize, 153fe4f1ce26ca41ef51b5245d70e93b502f76262a5Satoshi Kataoka const int *const xCoordinates, const int *const yCoordinates, const int *const times, 154fe4f1ce26ca41ef51b5245d70e93b502f76262a5Satoshi Kataoka const bool isGeometric) const { 155fe4f1ce26ca41ef51b5245d70e93b502f76262a5Satoshi Kataoka if (isGeometric) { 156fe4f1ce26ca41ef51b5245d70e93b502f76262a5Satoshi Kataoka for (int i = 0; i < mSampledInputSize; ++i) { 157d7a8fbf6a9ec8828d4b6d1c615a6c605bbe5b72eSatoshi Kataoka const int index = mSampledInputIndice[i]; 158fe4f1ce26ca41ef51b5245d70e93b502f76262a5Satoshi Kataoka if (index > inputSize || xCoordinates[index] != mSampledInputXs[i] || 159d7a8fbf6a9ec8828d4b6d1c615a6c605bbe5b72eSatoshi Kataoka yCoordinates[index] != mSampledInputYs[i] || times[index] != mSampledTimes[i]) { 160fe4f1ce26ca41ef51b5245d70e93b502f76262a5Satoshi Kataoka return false; 161fe4f1ce26ca41ef51b5245d70e93b502f76262a5Satoshi Kataoka } 162fe4f1ce26ca41ef51b5245d70e93b502f76262a5Satoshi Kataoka } 163fe4f1ce26ca41ef51b5245d70e93b502f76262a5Satoshi Kataoka } else { 164fe4f1ce26ca41ef51b5245d70e93b502f76262a5Satoshi Kataoka if (inputSize < mSampledInputSize) { 165fe4f1ce26ca41ef51b5245d70e93b502f76262a5Satoshi Kataoka // Assuming the cache is invalid if the previous input size is larger than the new one. 166096f35ff4b5413906e2a339663baf16e5dabaf64Keisuke Kuroyanagi return false; 167096f35ff4b5413906e2a339663baf16e5dabaf64Keisuke Kuroyanagi } 1685db594abbad2d9e8d2cf1aa6e417aa50ffc5dfc1Ken Wakasa for (int i = 0; i < mSampledInputSize && i < MAX_WORD_LENGTH; ++i) { 169fe4f1ce26ca41ef51b5245d70e93b502f76262a5Satoshi Kataoka if (xCoordinates[i] != mSampledInputXs[i] 170fe4f1ce26ca41ef51b5245d70e93b502f76262a5Satoshi Kataoka || yCoordinates[i] != mSampledInputYs[i]) { 171fe4f1ce26ca41ef51b5245d70e93b502f76262a5Satoshi Kataoka return false; 172fe4f1ce26ca41ef51b5245d70e93b502f76262a5Satoshi Kataoka } 173fe4f1ce26ca41ef51b5245d70e93b502f76262a5Satoshi Kataoka } 174096f35ff4b5413906e2a339663baf16e5dabaf64Keisuke Kuroyanagi } 175096f35ff4b5413906e2a339663baf16e5dabaf64Keisuke Kuroyanagi return true; 176096f35ff4b5413906e2a339663baf16e5dabaf64Keisuke Kuroyanagi} 177096f35ff4b5413906e2a339663baf16e5dabaf64Keisuke Kuroyanagi 178687a244703a02323ebd64433cbaead5def499861Satoshi Kataokaint ProximityInfoState::getDuration(const int index) const { 179feec20a692c9ffdecf7855a45531a12f129086caSatoshi Kataoka if (index >= 0 && index < mSampledInputSize - 1) { 180d7a8fbf6a9ec8828d4b6d1c615a6c605bbe5b72eSatoshi Kataoka return mSampledTimes[index + 1] - mSampledTimes[index]; 181687a244703a02323ebd64433cbaead5def499861Satoshi Kataoka } 18237b153e205c9672b299b47e97921fee2462a78bbSatoshi Kataoka return 0; 183687a244703a02323ebd64433cbaead5def499861Satoshi Kataoka} 184687a244703a02323ebd64433cbaead5def499861Satoshi Kataoka 1850519fdd18ac4414b8298d3338db1c8ccce032170Satoshi Kataoka// TODO: Remove the "scale" parameter 1860519fdd18ac4414b8298d3338db1c8ccce032170Satoshi Kataoka// This function basically converts from a length to an edit distance. Accordingly, it's obviously 1870519fdd18ac4414b8298d3338db1c8ccce032170Satoshi Kataoka// wrong to compare with mMaxPointToKeyLength. 1880519fdd18ac4414b8298d3338db1c8ccce032170Satoshi Kataokafloat ProximityInfoState::getPointToKeyLength( 1890519fdd18ac4414b8298d3338db1c8ccce032170Satoshi Kataoka const int inputIndex, const int codePoint, const float scale) const { 190ff74cc3e5e75fc0c6b9ffaa5e68d879775dc6115Keisuke Kuroyanagi const int keyId = mProximityInfo->getKeyIndexOf(codePoint); 191ff74cc3e5e75fc0c6b9ffaa5e68d879775dc6115Keisuke Kuroyanagi if (keyId != NOT_AN_INDEX) { 192ff74cc3e5e75fc0c6b9ffaa5e68d879775dc6115Keisuke Kuroyanagi const int index = inputIndex * mProximityInfo->getKeyCount() + keyId; 193e5aad5646309e80e1cd71533fb47a6be43f3aa2fSatoshi Kataoka return min(mSampledDistanceCache_G[index] * scale, mMaxPointToKeyLength); 194ff74cc3e5e75fc0c6b9ffaa5e68d879775dc6115Keisuke Kuroyanagi } 1951e61493c50082264caaef862df02b1ccc84dc396Ken Wakasa if (isSkippableCodePoint(codePoint)) { 196806eba452423e5e5971ef096dfae3fed180db665Keisuke Kuroyanagi return 0.0f; 197806eba452423e5e5971ef096dfae3fed180db665Keisuke Kuroyanagi } 198ff74cc3e5e75fc0c6b9ffaa5e68d879775dc6115Keisuke Kuroyanagi // If the char is not a key on the keyboard then return the max length. 199ff74cc3e5e75fc0c6b9ffaa5e68d879775dc6115Keisuke Kuroyanagi return MAX_POINT_TO_KEY_LENGTH; 200806eba452423e5e5971ef096dfae3fed180db665Keisuke Kuroyanagi} 201806eba452423e5e5971ef096dfae3fed180db665Keisuke Kuroyanagi 202a9763f93d76f97b9c6ed7dd1369a4d8cb016f06fSatoshi Kataokafloat ProximityInfoState::getPointToKeyLength_G(const int inputIndex, const int codePoint) const { 2030519fdd18ac4414b8298d3338db1c8ccce032170Satoshi Kataoka return getPointToKeyLength(inputIndex, codePoint, 1.0f); 2040519fdd18ac4414b8298d3338db1c8ccce032170Satoshi Kataoka} 2050519fdd18ac4414b8298d3338db1c8ccce032170Satoshi Kataoka 2060519fdd18ac4414b8298d3338db1c8ccce032170Satoshi Kataoka// TODO: Remove the "scale" parameter 2070519fdd18ac4414b8298d3338db1c8ccce032170Satoshi Kataokafloat ProximityInfoState::getPointToKeyByIdLength( 2080519fdd18ac4414b8298d3338db1c8ccce032170Satoshi Kataoka const int inputIndex, const int keyId, const float scale) const { 209d4828d5053ac30476b884c177235be0cac982c92Satoshi Kataoka return ProximityInfoStateUtils::getPointToKeyByIdLength(mMaxPointToKeyLength, 210e5aad5646309e80e1cd71533fb47a6be43f3aa2fSatoshi Kataoka &mSampledDistanceCache_G, mProximityInfo->getKeyCount(), inputIndex, keyId, scale); 211687a244703a02323ebd64433cbaead5def499861Satoshi Kataoka} 212687a244703a02323ebd64433cbaead5def499861Satoshi Kataoka 2130519fdd18ac4414b8298d3338db1c8ccce032170Satoshi Kataokafloat ProximityInfoState::getPointToKeyByIdLength(const int inputIndex, const int keyId) const { 2140519fdd18ac4414b8298d3338db1c8ccce032170Satoshi Kataoka return getPointToKeyByIdLength(inputIndex, keyId, 1.0f); 2150519fdd18ac4414b8298d3338db1c8ccce032170Satoshi Kataoka} 2160519fdd18ac4414b8298d3338db1c8ccce032170Satoshi Kataoka 2172c2f3a90d8115777adbe9ffd597f344aede84276Ken Wakasa// In the following function, c is the current character of the dictionary word currently examined. 2182c2f3a90d8115777adbe9ffd597f344aede84276Ken Wakasa// currentChars is an array containing the keys close to the character the user actually typed at 2192c2f3a90d8115777adbe9ffd597f344aede84276Ken Wakasa// the same position. We want to see if c is in it: if so, then the word contains at that position 2202c2f3a90d8115777adbe9ffd597f344aede84276Ken Wakasa// a character close to what the user typed. 2212c2f3a90d8115777adbe9ffd597f344aede84276Ken Wakasa// What the user typed is actually the first character of the array. 2222c2f3a90d8115777adbe9ffd597f344aede84276Ken Wakasa// proximityIndex is a pointer to the variable where getMatchedProximityId returns the index of c 2232c2f3a90d8115777adbe9ffd597f344aede84276Ken Wakasa// in the proximity chars of the input index. 2242c2f3a90d8115777adbe9ffd597f344aede84276Ken Wakasa// Notice : accented characters do not have a proximity list, so they are alone in their list. The 2252c2f3a90d8115777adbe9ffd597f344aede84276Ken Wakasa// non-accented version of the character should be considered "close", but not the other keys close 2262c2f3a90d8115777adbe9ffd597f344aede84276Ken Wakasa// to the non-accented version. 2272c2f3a90d8115777adbe9ffd597f344aede84276Ken WakasaProximityType ProximityInfoState::getMatchedProximityId(const int index, const int c, 2282c2f3a90d8115777adbe9ffd597f344aede84276Ken Wakasa const bool checkProximityChars, int *proximityIndex) const { 2292c2f3a90d8115777adbe9ffd597f344aede84276Ken Wakasa const int *currentCodePoints = getProximityCodePointsAt(index); 2302c2f3a90d8115777adbe9ffd597f344aede84276Ken Wakasa const int firstCodePoint = currentCodePoints[0]; 2312c2f3a90d8115777adbe9ffd597f344aede84276Ken Wakasa const int baseLowerC = toBaseLowerCase(c); 2322c2f3a90d8115777adbe9ffd597f344aede84276Ken Wakasa 2332c2f3a90d8115777adbe9ffd597f344aede84276Ken Wakasa // The first char in the array is what user typed. If it matches right away, that means the 2342c2f3a90d8115777adbe9ffd597f344aede84276Ken Wakasa // user typed that same char for this pos. 2352c2f3a90d8115777adbe9ffd597f344aede84276Ken Wakasa if (firstCodePoint == baseLowerC || firstCodePoint == c) { 2362c2f3a90d8115777adbe9ffd597f344aede84276Ken Wakasa return EQUIVALENT_CHAR; 2372c2f3a90d8115777adbe9ffd597f344aede84276Ken Wakasa } 2382c2f3a90d8115777adbe9ffd597f344aede84276Ken Wakasa 2392c2f3a90d8115777adbe9ffd597f344aede84276Ken Wakasa if (!checkProximityChars) return UNRELATED_CHAR; 2402c2f3a90d8115777adbe9ffd597f344aede84276Ken Wakasa 2412c2f3a90d8115777adbe9ffd597f344aede84276Ken Wakasa // If the non-accented, lowercased version of that first character matches c, then we have a 2422c2f3a90d8115777adbe9ffd597f344aede84276Ken Wakasa // non-accented version of the accented character the user typed. Treat it as a close char. 2432c2f3a90d8115777adbe9ffd597f344aede84276Ken Wakasa if (toBaseLowerCase(firstCodePoint) == baseLowerC) { 2442c2f3a90d8115777adbe9ffd597f344aede84276Ken Wakasa return NEAR_PROXIMITY_CHAR; 2452c2f3a90d8115777adbe9ffd597f344aede84276Ken Wakasa } 2462c2f3a90d8115777adbe9ffd597f344aede84276Ken Wakasa 2472c2f3a90d8115777adbe9ffd597f344aede84276Ken Wakasa // Not an exact nor an accent-alike match: search the list of close keys 2482c2f3a90d8115777adbe9ffd597f344aede84276Ken Wakasa int j = 1; 2496c22439bf80da08576e86c1282afc5cfa431e235Ken Wakasa while (j < MAX_PROXIMITY_CHARS_SIZE 2502c2f3a90d8115777adbe9ffd597f344aede84276Ken Wakasa && currentCodePoints[j] > ADDITIONAL_PROXIMITY_CHAR_DELIMITER_CODE) { 2512c2f3a90d8115777adbe9ffd597f344aede84276Ken Wakasa const bool matched = (currentCodePoints[j] == baseLowerC || currentCodePoints[j] == c); 2522c2f3a90d8115777adbe9ffd597f344aede84276Ken Wakasa if (matched) { 2532c2f3a90d8115777adbe9ffd597f344aede84276Ken Wakasa if (proximityIndex) { 2542c2f3a90d8115777adbe9ffd597f344aede84276Ken Wakasa *proximityIndex = j; 2552c2f3a90d8115777adbe9ffd597f344aede84276Ken Wakasa } 2562c2f3a90d8115777adbe9ffd597f344aede84276Ken Wakasa return NEAR_PROXIMITY_CHAR; 2572c2f3a90d8115777adbe9ffd597f344aede84276Ken Wakasa } 2582c2f3a90d8115777adbe9ffd597f344aede84276Ken Wakasa ++j; 2592c2f3a90d8115777adbe9ffd597f344aede84276Ken Wakasa } 2606c22439bf80da08576e86c1282afc5cfa431e235Ken Wakasa if (j < MAX_PROXIMITY_CHARS_SIZE 2612c2f3a90d8115777adbe9ffd597f344aede84276Ken Wakasa && currentCodePoints[j] == ADDITIONAL_PROXIMITY_CHAR_DELIMITER_CODE) { 2622c2f3a90d8115777adbe9ffd597f344aede84276Ken Wakasa ++j; 2636c22439bf80da08576e86c1282afc5cfa431e235Ken Wakasa while (j < MAX_PROXIMITY_CHARS_SIZE 2642c2f3a90d8115777adbe9ffd597f344aede84276Ken Wakasa && currentCodePoints[j] > ADDITIONAL_PROXIMITY_CHAR_DELIMITER_CODE) { 2652c2f3a90d8115777adbe9ffd597f344aede84276Ken Wakasa const bool matched = (currentCodePoints[j] == baseLowerC || currentCodePoints[j] == c); 2662c2f3a90d8115777adbe9ffd597f344aede84276Ken Wakasa if (matched) { 2672c2f3a90d8115777adbe9ffd597f344aede84276Ken Wakasa if (proximityIndex) { 2682c2f3a90d8115777adbe9ffd597f344aede84276Ken Wakasa *proximityIndex = j; 2692c2f3a90d8115777adbe9ffd597f344aede84276Ken Wakasa } 2702c2f3a90d8115777adbe9ffd597f344aede84276Ken Wakasa return ADDITIONAL_PROXIMITY_CHAR; 2712c2f3a90d8115777adbe9ffd597f344aede84276Ken Wakasa } 2722c2f3a90d8115777adbe9ffd597f344aede84276Ken Wakasa ++j; 2732c2f3a90d8115777adbe9ffd597f344aede84276Ken Wakasa } 2742c2f3a90d8115777adbe9ffd597f344aede84276Ken Wakasa } 2752c2f3a90d8115777adbe9ffd597f344aede84276Ken Wakasa // Was not included, signal this as an unrelated character. 2762c2f3a90d8115777adbe9ffd597f344aede84276Ken Wakasa return UNRELATED_CHAR; 2772c2f3a90d8115777adbe9ffd597f344aede84276Ken Wakasa} 2782c2f3a90d8115777adbe9ffd597f344aede84276Ken Wakasa 2793811a28ddc07201930e0bbd2e1d01045b59af308Keisuke Kuroyanagiint ProximityInfoState::getSpaceY() const { 280b02ee3d67a1884b6ff59cc16c29a476845c0694fKen Wakasa const int keyId = mProximityInfo->getKeyIndexOf(KEYCODE_SPACE); 281f2789819bd005b5b0581e8439601b5501306327dKen Wakasa return mProximityInfo->getKeyCenterYOfKeyIdG(keyId); 282687a244703a02323ebd64433cbaead5def499861Satoshi Kataoka} 283687a244703a02323ebd64433cbaead5def499861Satoshi Kataoka 28495a49a527ac9c2c97cfcc758bd6f0d58fb4ad9c0Keisuke Kuroyanagi// Puts possible characters into filter and returns new filter size. 285082507e1da56c6cefe575ec3d6a334e9b717e3faKen Wakasaint ProximityInfoState::getAllPossibleChars( 286082507e1da56c6cefe575ec3d6a334e9b717e3faKen Wakasa const size_t index, int *const filter, const int filterSize) const { 287feec20a692c9ffdecf7855a45531a12f129086caSatoshi Kataoka if (index >= mSampledInputXs.size()) { 28895a49a527ac9c2c97cfcc758bd6f0d58fb4ad9c0Keisuke Kuroyanagi return filterSize; 28995a49a527ac9c2c97cfcc758bd6f0d58fb4ad9c0Keisuke Kuroyanagi } 29041f12ee27b269033fe818f7d52e81ba948a046c3Keisuke Kuroyanagi int newFilterSize = filterSize; 291ff74cc3e5e75fc0c6b9ffaa5e68d879775dc6115Keisuke Kuroyanagi const int keyCount = mProximityInfo->getKeyCount(); 292ff74cc3e5e75fc0c6b9ffaa5e68d879775dc6115Keisuke Kuroyanagi for (int j = 0; j < keyCount; ++j) { 293e5aad5646309e80e1cd71533fb47a6be43f3aa2fSatoshi Kataoka if (mSampledSearchKeysVector[index].test(j)) { 294082507e1da56c6cefe575ec3d6a334e9b717e3faKen Wakasa const int keyCodePoint = mProximityInfo->getCodePointOf(j); 29595a49a527ac9c2c97cfcc758bd6f0d58fb4ad9c0Keisuke Kuroyanagi bool insert = true; 29695a49a527ac9c2c97cfcc758bd6f0d58fb4ad9c0Keisuke Kuroyanagi // TODO: Avoid linear search 29795a49a527ac9c2c97cfcc758bd6f0d58fb4ad9c0Keisuke Kuroyanagi for (int k = 0; k < filterSize; ++k) { 29895a49a527ac9c2c97cfcc758bd6f0d58fb4ad9c0Keisuke Kuroyanagi if (filter[k] == keyCodePoint) { 29995a49a527ac9c2c97cfcc758bd6f0d58fb4ad9c0Keisuke Kuroyanagi insert = false; 30095a49a527ac9c2c97cfcc758bd6f0d58fb4ad9c0Keisuke Kuroyanagi break; 30195a49a527ac9c2c97cfcc758bd6f0d58fb4ad9c0Keisuke Kuroyanagi } 30295a49a527ac9c2c97cfcc758bd6f0d58fb4ad9c0Keisuke Kuroyanagi } 30395a49a527ac9c2c97cfcc758bd6f0d58fb4ad9c0Keisuke Kuroyanagi if (insert) { 30441f12ee27b269033fe818f7d52e81ba948a046c3Keisuke Kuroyanagi filter[newFilterSize++] = keyCodePoint; 30595a49a527ac9c2c97cfcc758bd6f0d58fb4ad9c0Keisuke Kuroyanagi } 30695a49a527ac9c2c97cfcc758bd6f0d58fb4ad9c0Keisuke Kuroyanagi } 30795a49a527ac9c2c97cfcc758bd6f0d58fb4ad9c0Keisuke Kuroyanagi } 30841f12ee27b269033fe818f7d52e81ba948a046c3Keisuke Kuroyanagi return newFilterSize; 30995a49a527ac9c2c97cfcc758bd6f0d58fb4ad9c0Keisuke Kuroyanagi} 3103811a28ddc07201930e0bbd2e1d01045b59af308Keisuke Kuroyanagi 311ff74cc3e5e75fc0c6b9ffaa5e68d879775dc6115Keisuke Kuroyanagibool ProximityInfoState::isKeyInSerchKeysAfterIndex(const int index, const int keyId) const { 312ff74cc3e5e75fc0c6b9ffaa5e68d879775dc6115Keisuke Kuroyanagi ASSERT(keyId >= 0); 313feec20a692c9ffdecf7855a45531a12f129086caSatoshi Kataoka ASSERT(index >= 0 && index < mSampledInputSize); 314e5aad5646309e80e1cd71533fb47a6be43f3aa2fSatoshi Kataoka return mSampledSearchKeysVector[index].test(keyId); 315ff74cc3e5e75fc0c6b9ffaa5e68d879775dc6115Keisuke Kuroyanagi} 316ff74cc3e5e75fc0c6b9ffaa5e68d879775dc6115Keisuke Kuroyanagi 317096f35ff4b5413906e2a339663baf16e5dabaf64Keisuke Kuroyanagivoid ProximityInfoState::popInputData() { 318d7a8fbf6a9ec8828d4b6d1c615a6c605bbe5b72eSatoshi Kataoka ProximityInfoStateUtils::popInputData(&mSampledInputXs, &mSampledInputYs, &mSampledTimes, 319d7a8fbf6a9ec8828d4b6d1c615a6c605bbe5b72eSatoshi Kataoka &mSampledLengthCache, &mSampledInputIndice); 320096f35ff4b5413906e2a339663baf16e5dabaf64Keisuke Kuroyanagi} 321096f35ff4b5413906e2a339663baf16e5dabaf64Keisuke Kuroyanagi 322ff74cc3e5e75fc0c6b9ffaa5e68d879775dc6115Keisuke Kuroyanagifloat ProximityInfoState::getDirection(const int index0, const int index1) const { 323ee62b78c9675bddaf2437e0cf521f6115e1d9febSatoshi Kataoka return ProximityInfoStateUtils::getDirection( 324ee62b78c9675bddaf2437e0cf521f6115e1d9febSatoshi Kataoka &mSampledInputXs, &mSampledInputYs, index0, index1); 325ff74cc3e5e75fc0c6b9ffaa5e68d879775dc6115Keisuke Kuroyanagi} 326ff74cc3e5e75fc0c6b9ffaa5e68d879775dc6115Keisuke Kuroyanagi 327ff74cc3e5e75fc0c6b9ffaa5e68d879775dc6115Keisuke Kuroyanagifloat ProximityInfoState::getLineToKeyDistance( 328ff74cc3e5e75fc0c6b9ffaa5e68d879775dc6115Keisuke Kuroyanagi const int from, const int to, const int keyId, const bool extend) const { 329feec20a692c9ffdecf7855a45531a12f129086caSatoshi Kataoka if (from < 0 || from > mSampledInputSize - 1) { 330ff74cc3e5e75fc0c6b9ffaa5e68d879775dc6115Keisuke Kuroyanagi return 0.0f; 331ff74cc3e5e75fc0c6b9ffaa5e68d879775dc6115Keisuke Kuroyanagi } 332feec20a692c9ffdecf7855a45531a12f129086caSatoshi Kataoka if (to < 0 || to > mSampledInputSize - 1) { 333ff74cc3e5e75fc0c6b9ffaa5e68d879775dc6115Keisuke Kuroyanagi return 0.0f; 334ff74cc3e5e75fc0c6b9ffaa5e68d879775dc6115Keisuke Kuroyanagi } 335feec20a692c9ffdecf7855a45531a12f129086caSatoshi Kataoka const int x0 = mSampledInputXs[from]; 336feec20a692c9ffdecf7855a45531a12f129086caSatoshi Kataoka const int y0 = mSampledInputYs[from]; 337feec20a692c9ffdecf7855a45531a12f129086caSatoshi Kataoka const int x1 = mSampledInputXs[to]; 338feec20a692c9ffdecf7855a45531a12f129086caSatoshi Kataoka const int y1 = mSampledInputYs[to]; 339ff74cc3e5e75fc0c6b9ffaa5e68d879775dc6115Keisuke Kuroyanagi 340ff74cc3e5e75fc0c6b9ffaa5e68d879775dc6115Keisuke Kuroyanagi const int keyX = mProximityInfo->getKeyCenterXOfKeyIdG(keyId); 341ff74cc3e5e75fc0c6b9ffaa5e68d879775dc6115Keisuke Kuroyanagi const int keyY = mProximityInfo->getKeyCenterYOfKeyIdG(keyId); 342ff74cc3e5e75fc0c6b9ffaa5e68d879775dc6115Keisuke Kuroyanagi 3430c2227ab991774768414d8ea60a469f005eb9f1aKen Wakasa return ProximityInfoUtils::pointToLineSegSquaredDistanceFloat( 3440c2227ab991774768414d8ea60a469f005eb9f1aKen Wakasa keyX, keyY, x0, y0, x1, y1, extend); 345806eba452423e5e5971ef096dfae3fed180db665Keisuke Kuroyanagi} 346806eba452423e5e5971ef096dfae3fed180db665Keisuke Kuroyanagi 347e0349619acdba79223390c9925d81f7e88c7f8adSatoshi Kataoka// Get a word that is detected by tracing the most probable string into codePointBuf and 3481e61493c50082264caaef862df02b1ccc84dc396Ken Wakasa// returns probability of generating the word. 349e0349619acdba79223390c9925d81f7e88c7f8adSatoshi Kataokafloat ProximityInfoState::getMostProbableString(int *const codePointBuf) const { 350350309aeb81ad1924af4d2e6d0bceaa6f98e4821Keisuke Kuroyanagi static const float DEMOTION_LOG_PROBABILITY = 0.3f; 351ff74cc3e5e75fc0c6b9ffaa5e68d879775dc6115Keisuke Kuroyanagi int index = 0; 352ff74cc3e5e75fc0c6b9ffaa5e68d879775dc6115Keisuke Kuroyanagi float sumLogProbability = 0.0f; 353806eba452423e5e5971ef096dfae3fed180db665Keisuke Kuroyanagi // TODO: Current implementation is greedy algorithm. DP would be efficient for many cases. 3545db594abbad2d9e8d2cf1aa6e417aa50ffc5dfc1Ken Wakasa for (int i = 0; i < mSampledInputSize && index < MAX_WORD_LENGTH - 1; ++i) { 355ff74cc3e5e75fc0c6b9ffaa5e68d879775dc6115Keisuke Kuroyanagi float minLogProbability = static_cast<float>(MAX_POINT_TO_KEY_LENGTH); 356ff74cc3e5e75fc0c6b9ffaa5e68d879775dc6115Keisuke Kuroyanagi int character = NOT_AN_INDEX; 357806eba452423e5e5971ef096dfae3fed180db665Keisuke Kuroyanagi for (hash_map_compat<int, float>::const_iterator it = mCharProbabilities[i].begin(); 358806eba452423e5e5971ef096dfae3fed180db665Keisuke Kuroyanagi it != mCharProbabilities[i].end(); ++it) { 359ff74cc3e5e75fc0c6b9ffaa5e68d879775dc6115Keisuke Kuroyanagi const float logProbability = (it->first != NOT_AN_INDEX) 360350309aeb81ad1924af4d2e6d0bceaa6f98e4821Keisuke Kuroyanagi ? it->second + DEMOTION_LOG_PROBABILITY : it->second; 361ff74cc3e5e75fc0c6b9ffaa5e68d879775dc6115Keisuke Kuroyanagi if (logProbability < minLogProbability) { 362ff74cc3e5e75fc0c6b9ffaa5e68d879775dc6115Keisuke Kuroyanagi minLogProbability = logProbability; 363ff74cc3e5e75fc0c6b9ffaa5e68d879775dc6115Keisuke Kuroyanagi character = it->first; 364806eba452423e5e5971ef096dfae3fed180db665Keisuke Kuroyanagi } 365806eba452423e5e5971ef096dfae3fed180db665Keisuke Kuroyanagi } 366ff74cc3e5e75fc0c6b9ffaa5e68d879775dc6115Keisuke Kuroyanagi if (character != NOT_AN_INDEX) { 3671e61493c50082264caaef862df02b1ccc84dc396Ken Wakasa codePointBuf[index] = mProximityInfo->getCodePointOf(character); 368806eba452423e5e5971ef096dfae3fed180db665Keisuke Kuroyanagi index++; 369806eba452423e5e5971ef096dfae3fed180db665Keisuke Kuroyanagi } 370ff74cc3e5e75fc0c6b9ffaa5e68d879775dc6115Keisuke Kuroyanagi sumLogProbability += minLogProbability; 371806eba452423e5e5971ef096dfae3fed180db665Keisuke Kuroyanagi } 3721e61493c50082264caaef862df02b1ccc84dc396Ken Wakasa codePointBuf[index] = '\0'; 373ff74cc3e5e75fc0c6b9ffaa5e68d879775dc6115Keisuke Kuroyanagi return sumLogProbability; 374ff74cc3e5e75fc0c6b9ffaa5e68d879775dc6115Keisuke Kuroyanagi} 375ff74cc3e5e75fc0c6b9ffaa5e68d879775dc6115Keisuke Kuroyanagi 376f32869c6b6296a8bf594abdf0b18281d9312e54fSatoshi Kataokabool ProximityInfoState::hasSpaceProximity(const int index) const { 377f32869c6b6296a8bf594abdf0b18281d9312e54fSatoshi Kataoka ASSERT(0 <= index && index < mSampledInputSize); 378f32869c6b6296a8bf594abdf0b18281d9312e54fSatoshi Kataoka return mProximityInfo->hasSpaceProximity(getInputX(index), getInputY(index)); 379f32869c6b6296a8bf594abdf0b18281d9312e54fSatoshi Kataoka} 380f32869c6b6296a8bf594abdf0b18281d9312e54fSatoshi Kataoka 381ff74cc3e5e75fc0c6b9ffaa5e68d879775dc6115Keisuke Kuroyanagi// Returns a probability of mapping index to keyIndex. 382ff74cc3e5e75fc0c6b9ffaa5e68d879775dc6115Keisuke Kuroyanagifloat ProximityInfoState::getProbability(const int index, const int keyIndex) const { 383feec20a692c9ffdecf7855a45531a12f129086caSatoshi Kataoka ASSERT(0 <= index && index < mSampledInputSize); 384ff74cc3e5e75fc0c6b9ffaa5e68d879775dc6115Keisuke Kuroyanagi hash_map_compat<int, float>::const_iterator it = mCharProbabilities[index].find(keyIndex); 385ff74cc3e5e75fc0c6b9ffaa5e68d879775dc6115Keisuke Kuroyanagi if (it != mCharProbabilities[index].end()) { 386ff74cc3e5e75fc0c6b9ffaa5e68d879775dc6115Keisuke Kuroyanagi return it->second; 387ff74cc3e5e75fc0c6b9ffaa5e68d879775dc6115Keisuke Kuroyanagi } 388ff74cc3e5e75fc0c6b9ffaa5e68d879775dc6115Keisuke Kuroyanagi return static_cast<float>(MAX_POINT_TO_KEY_LENGTH); 389806eba452423e5e5971ef096dfae3fed180db665Keisuke Kuroyanagi} 3903e8c58f68d53e6cc9dbf59201c7bdfb8ad04a1cdSatoshi Kataoka} // namespace latinime 391