proximity_info_state.cpp revision e5cdd21102e4e49b18c696261a084783eb6d7e7a
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 1720b6775acc957896bdb038dfd99794d6cd7cea5aSatoshi Kataoka#include <cstring> // for memset() and memcpy() 18806eba452423e5e5971ef096dfae3fed180db665Keisuke Kuroyanagi#include <sstream> // for debug prints 19e5cdd21102e4e49b18c696261a084783eb6d7e7aSatoshi Kataoka#include <vector> 203e8c58f68d53e6cc9dbf59201c7bdfb8ad04a1cdSatoshi Kataoka 213e8c58f68d53e6cc9dbf59201c7bdfb8ad04a1cdSatoshi Kataoka#define LOG_TAG "LatinIME: proximity_info_state.cpp" 223e8c58f68d53e6cc9dbf59201c7bdfb8ad04a1cdSatoshi Kataoka 233e8c58f68d53e6cc9dbf59201c7bdfb8ad04a1cdSatoshi Kataoka#include "defines.h" 246cee61deebd0ca2b85054ccc239523d1e5fdfab1Ken Wakasa#include "geometry_utils.h" 253e8c58f68d53e6cc9dbf59201c7bdfb8ad04a1cdSatoshi Kataoka#include "proximity_info.h" 263e8c58f68d53e6cc9dbf59201c7bdfb8ad04a1cdSatoshi Kataoka#include "proximity_info_state.h" 2747cc52415e3affb83eb4369190425b2a17b956c5Satoshi Kataoka#include "proximity_info_state_utils.h" 283e8c58f68d53e6cc9dbf59201c7bdfb8ad04a1cdSatoshi Kataoka 293e8c58f68d53e6cc9dbf59201c7bdfb8ad04a1cdSatoshi Kataokanamespace latinime { 30764dd712032d7b8012797b1116b523bef7b907f3Ken Wakasa 31233aad5e5c7567a97af30f38f50a65365f729dfeSatoshi Kataokavoid ProximityInfoState::initInputParams(const int pointerId, const float maxPointToKeyLength, 321e61493c50082264caaef862df02b1ccc84dc396Ken Wakasa const ProximityInfo *proximityInfo, const int *const inputCodes, const int inputSize, 33687a244703a02323ebd64433cbaead5def499861Satoshi Kataoka const int *const xCoordinates, const int *const yCoordinates, const int *const times, 34687a244703a02323ebd64433cbaead5def499861Satoshi Kataoka const int *const pointerIds, const bool isGeometric) { 359d18c6dd38c4d5632a5d5a5c26f567b9f6f7f969Satoshi Kataoka ASSERT(isGeometric || (inputSize < MAX_WORD_LENGTH)); 369d18c6dd38c4d5632a5d5a5c26f567b9f6f7f969Satoshi Kataoka mIsContinuationPossible = ProximityInfoStateUtils::checkAndReturnIsContinuationPossible( 379d18c6dd38c4d5632a5d5a5c26f567b9f6f7f969Satoshi Kataoka inputSize, xCoordinates, yCoordinates, times, mSampledInputSize, &mSampledInputXs, 389d18c6dd38c4d5632a5d5a5c26f567b9f6f7f969Satoshi Kataoka &mSampledInputYs, &mSampledTimes, &mSampledInputIndice); 39096f35ff4b5413906e2a339663baf16e5dabaf64Keisuke Kuroyanagi 404a3db7057f77dc85311fb1f94934b5a004ab613eSatoshi Kataoka mProximityInfo = proximityInfo; 414a3db7057f77dc85311fb1f94934b5a004ab613eSatoshi Kataoka mHasTouchPositionCorrectionData = proximityInfo->hasTouchPositionCorrectionData(); 424a3db7057f77dc85311fb1f94934b5a004ab613eSatoshi Kataoka mMostCommonKeyWidthSquare = proximityInfo->getMostCommonKeyWidthSquare(); 434a3db7057f77dc85311fb1f94934b5a004ab613eSatoshi Kataoka mKeyCount = proximityInfo->getKeyCount(); 444a3db7057f77dc85311fb1f94934b5a004ab613eSatoshi Kataoka mCellHeight = proximityInfo->getCellHeight(); 454a3db7057f77dc85311fb1f94934b5a004ab613eSatoshi Kataoka mCellWidth = proximityInfo->getCellWidth(); 464a3db7057f77dc85311fb1f94934b5a004ab613eSatoshi Kataoka mGridHeight = proximityInfo->getGridWidth(); 474a3db7057f77dc85311fb1f94934b5a004ab613eSatoshi Kataoka mGridWidth = proximityInfo->getGridHeight(); 483e8c58f68d53e6cc9dbf59201c7bdfb8ad04a1cdSatoshi Kataoka 49bf78e1371c12d819020d60f0e585f5e6c26e6aa2Satoshi Kataoka memset(mInputProximities, 0, sizeof(mInputProximities)); 503e8c58f68d53e6cc9dbf59201c7bdfb8ad04a1cdSatoshi Kataoka 5108f00cf55f2e083c1ed254a32495b622c9ad9862Satoshi Kataoka if (!isGeometric && pointerId == 0) { 52bf78e1371c12d819020d60f0e585f5e6c26e6aa2Satoshi Kataoka mProximityInfo->initializeProximities(inputCodes, xCoordinates, yCoordinates, 53bf78e1371c12d819020d60f0e585f5e6c26e6aa2Satoshi Kataoka inputSize, mInputProximities); 543e8c58f68d53e6cc9dbf59201c7bdfb8ad04a1cdSatoshi Kataoka } 55687a244703a02323ebd64433cbaead5def499861Satoshi Kataoka 56687a244703a02323ebd64433cbaead5def499861Satoshi Kataoka /////////////////////// 57687a244703a02323ebd64433cbaead5def499861Satoshi Kataoka // Setup touch points 58096f35ff4b5413906e2a339663baf16e5dabaf64Keisuke Kuroyanagi int pushTouchPointStartIndex = 0; 59096f35ff4b5413906e2a339663baf16e5dabaf64Keisuke Kuroyanagi int lastSavedInputSize = 0; 6008f00cf55f2e083c1ed254a32495b622c9ad9862Satoshi Kataoka mMaxPointToKeyLength = maxPointToKeyLength; 6120b6775acc957896bdb038dfd99794d6cd7cea5aSatoshi Kataoka mSampledInputSize = 0; 6220b6775acc957896bdb038dfd99794d6cd7cea5aSatoshi Kataoka mMostProbableStringProbability = 0.0f; 6320b6775acc957896bdb038dfd99794d6cd7cea5aSatoshi Kataoka 64d7a8fbf6a9ec8828d4b6d1c615a6c605bbe5b72eSatoshi Kataoka if (mIsContinuationPossible && mSampledInputIndice.size() > 1) { 65096f35ff4b5413906e2a339663baf16e5dabaf64Keisuke Kuroyanagi // Just update difference. 6620b6775acc957896bdb038dfd99794d6cd7cea5aSatoshi Kataoka // Previous two points are never skipped. Thus, we pop 2 input point data here. 6720b6775acc957896bdb038dfd99794d6cd7cea5aSatoshi Kataoka pushTouchPointStartIndex = ProximityInfoStateUtils::trimLastTwoTouchPoints( 6820b6775acc957896bdb038dfd99794d6cd7cea5aSatoshi Kataoka &mSampledInputXs, &mSampledInputYs, &mSampledTimes, &mSampledLengthCache, 6920b6775acc957896bdb038dfd99794d6cd7cea5aSatoshi Kataoka &mSampledInputIndice); 70feec20a692c9ffdecf7855a45531a12f129086caSatoshi Kataoka lastSavedInputSize = mSampledInputXs.size(); 71096f35ff4b5413906e2a339663baf16e5dabaf64Keisuke Kuroyanagi } else { 72096f35ff4b5413906e2a339663baf16e5dabaf64Keisuke Kuroyanagi // Clear all data. 73feec20a692c9ffdecf7855a45531a12f129086caSatoshi Kataoka mSampledInputXs.clear(); 74feec20a692c9ffdecf7855a45531a12f129086caSatoshi Kataoka mSampledInputYs.clear(); 75d7a8fbf6a9ec8828d4b6d1c615a6c605bbe5b72eSatoshi Kataoka mSampledTimes.clear(); 76d7a8fbf6a9ec8828d4b6d1c615a6c605bbe5b72eSatoshi Kataoka mSampledInputIndice.clear(); 77d7a8fbf6a9ec8828d4b6d1c615a6c605bbe5b72eSatoshi Kataoka mSampledLengthCache.clear(); 78e5aad5646309e80e1cd71533fb47a6be43f3aa2fSatoshi Kataoka mSampledDistanceCache_G.clear(); 79e5cdd21102e4e49b18c696261a084783eb6d7e7aSatoshi Kataoka mSampledNearKeySets.clear(); 80e5cdd21102e4e49b18c696261a084783eb6d7e7aSatoshi Kataoka mSampledSearchKeySets.clear(); 819af533538ea749d7c930bb3125fa4d3e4feb8478Satoshi Kataoka mSpeedRates.clear(); 826ae8dd4343445d2df4444388b605d2aa930fa2a0Satoshi Kataoka mBeelineSpeedPercentiles.clear(); 83806eba452423e5e5971ef096dfae3fed180db665Keisuke Kuroyanagi mCharProbabilities.clear(); 841e06a4d8e9e71188ed685282155ea52a48ddc050Keisuke Kuroyanagi mDirections.clear(); 85096f35ff4b5413906e2a339663baf16e5dabaf64Keisuke Kuroyanagi } 8620b6775acc957896bdb038dfd99794d6cd7cea5aSatoshi Kataoka 879182daf98c0d1db897e82b77c2196b7f9aad6f01Satoshi Kataoka if (DEBUG_GEO_FULL) { 889182daf98c0d1db897e82b77c2196b7f9aad6f01Satoshi Kataoka AKLOGI("Init ProximityInfoState: reused points = %d, last input size = %d", 899182daf98c0d1db897e82b77c2196b7f9aad6f01Satoshi Kataoka pushTouchPointStartIndex, lastSavedInputSize); 909182daf98c0d1db897e82b77c2196b7f9aad6f01Satoshi Kataoka } 91d9c10b19793b011f862e3dd31883f746044431d7Keisuke Kuroyanagi 92687a244703a02323ebd64433cbaead5def499861Satoshi Kataoka if (xCoordinates && yCoordinates) { 9328c008421cc5d97da8e470dbc934a2891daf9997Ken Wakasa mSampledInputSize = ProximityInfoStateUtils::updateTouchPoints(mProximityInfo, 9428c008421cc5d97da8e470dbc934a2891daf9997Ken Wakasa mMaxPointToKeyLength, mInputProximities, xCoordinates, yCoordinates, times, 9528c008421cc5d97da8e470dbc934a2891daf9997Ken Wakasa pointerIds, inputSize, isGeometric, pointerId, pushTouchPointStartIndex, 9628c008421cc5d97da8e470dbc934a2891daf9997Ken Wakasa &mSampledInputXs, &mSampledInputYs, &mSampledTimes, &mSampledLengthCache, 9728c008421cc5d97da8e470dbc934a2891daf9997Ken Wakasa &mSampledInputIndice); 983e8c58f68d53e6cc9dbf59201c7bdfb8ad04a1cdSatoshi Kataoka } 99687a244703a02323ebd64433cbaead5def499861Satoshi Kataoka 100feec20a692c9ffdecf7855a45531a12f129086caSatoshi Kataoka if (mSampledInputSize > 0 && isGeometric) { 10128c008421cc5d97da8e470dbc934a2891daf9997Ken Wakasa mAverageSpeed = ProximityInfoStateUtils::refreshSpeedRates(inputSize, xCoordinates, 10228c008421cc5d97da8e470dbc934a2891daf9997Ken Wakasa yCoordinates, times, lastSavedInputSize, mSampledInputSize, &mSampledInputXs, 10328c008421cc5d97da8e470dbc934a2891daf9997Ken Wakasa &mSampledInputYs, &mSampledTimes, &mSampledLengthCache, &mSampledInputIndice, 10428c008421cc5d97da8e470dbc934a2891daf9997Ken Wakasa &mSpeedRates, &mDirections); 10528c008421cc5d97da8e470dbc934a2891daf9997Ken Wakasa ProximityInfoStateUtils::refreshBeelineSpeedRates(mProximityInfo->getMostCommonKeyWidth(), 10628c008421cc5d97da8e470dbc934a2891daf9997Ken Wakasa mAverageSpeed, inputSize, xCoordinates, yCoordinates, times, mSampledInputSize, 10728c008421cc5d97da8e470dbc934a2891daf9997Ken Wakasa &mSampledInputXs, &mSampledInputYs, &mSampledInputIndice, 10828c008421cc5d97da8e470dbc934a2891daf9997Ken Wakasa &mBeelineSpeedPercentiles); 109ff74cc3e5e75fc0c6b9ffaa5e68d879775dc6115Keisuke Kuroyanagi } 110ff74cc3e5e75fc0c6b9ffaa5e68d879775dc6115Keisuke Kuroyanagi 111feec20a692c9ffdecf7855a45531a12f129086caSatoshi Kataoka if (mSampledInputSize > 0) { 11228c008421cc5d97da8e470dbc934a2891daf9997Ken Wakasa ProximityInfoStateUtils::initGeometricDistanceInfos(mProximityInfo, mSampledInputSize, 113e5cdd21102e4e49b18c696261a084783eb6d7e7aSatoshi Kataoka lastSavedInputSize, &mSampledInputXs, &mSampledInputYs, &mSampledNearKeySets, 11428c008421cc5d97da8e470dbc934a2891daf9997Ken Wakasa &mSampledDistanceCache_G); 115ff74cc3e5e75fc0c6b9ffaa5e68d879775dc6115Keisuke Kuroyanagi if (isGeometric) { 116ff74cc3e5e75fc0c6b9ffaa5e68d879775dc6115Keisuke Kuroyanagi // updates probabilities of skipping or mapping each key for all points. 117d4828d5053ac30476b884c177235be0cac982c92Satoshi Kataoka ProximityInfoStateUtils::updateAlignPointProbabilities( 118d4828d5053ac30476b884c177235be0cac982c92Satoshi Kataoka mMaxPointToKeyLength, mProximityInfo->getMostCommonKeyWidth(), 119d7a8fbf6a9ec8828d4b6d1c615a6c605bbe5b72eSatoshi Kataoka mProximityInfo->getKeyCount(), lastSavedInputSize, mSampledInputSize, 120d7a8fbf6a9ec8828d4b6d1c615a6c605bbe5b72eSatoshi Kataoka &mSampledInputXs, &mSampledInputYs, &mSpeedRates, &mSampledLengthCache, 121e5cdd21102e4e49b18c696261a084783eb6d7e7aSatoshi Kataoka &mSampledDistanceCache_G, &mSampledNearKeySets, &mCharProbabilities); 122e5cdd21102e4e49b18c696261a084783eb6d7e7aSatoshi Kataoka ProximityInfoStateUtils::updateSampledSearchKeySets(mProximityInfo, 123e5aad5646309e80e1cd71533fb47a6be43f3aa2fSatoshi Kataoka mSampledInputSize, lastSavedInputSize, &mSampledLengthCache, 124e5cdd21102e4e49b18c696261a084783eb6d7e7aSatoshi Kataoka &mSampledNearKeySets, &mSampledSearchKeySets, 125e5cdd21102e4e49b18c696261a084783eb6d7e7aSatoshi Kataoka &mSampledSearchKeyVectors); 12620b6775acc957896bdb038dfd99794d6cd7cea5aSatoshi Kataoka mMostProbableStringProbability = ProximityInfoStateUtils::getMostProbableString( 12720b6775acc957896bdb038dfd99794d6cd7cea5aSatoshi Kataoka mProximityInfo, mSampledInputSize, &mCharProbabilities, mMostProbableString); 12820b6775acc957896bdb038dfd99794d6cd7cea5aSatoshi Kataoka 129687a244703a02323ebd64433cbaead5def499861Satoshi Kataoka } 130687a244703a02323ebd64433cbaead5def499861Satoshi Kataoka } 13108f00cf55f2e083c1ed254a32495b622c9ad9862Satoshi Kataoka 132806eba452423e5e5971ef096dfae3fed180db665Keisuke Kuroyanagi if (DEBUG_SAMPLING_POINTS) { 133d7a8fbf6a9ec8828d4b6d1c615a6c605bbe5b72eSatoshi Kataoka ProximityInfoStateUtils::dump(isGeometric, inputSize, xCoordinates, yCoordinates, 134e2912d17e4dab75b81f4c9e41a539e491ac059caSatoshi Kataoka mSampledInputSize, &mSampledInputXs, &mSampledInputYs, &mSampledTimes, &mSpeedRates, 135d7a8fbf6a9ec8828d4b6d1c615a6c605bbe5b72eSatoshi Kataoka &mBeelineSpeedPercentiles); 136806eba452423e5e5971ef096dfae3fed180db665Keisuke Kuroyanagi } 137687a244703a02323ebd64433cbaead5def499861Satoshi Kataoka // end 138687a244703a02323ebd64433cbaead5def499861Satoshi Kataoka /////////////////////// 139687a244703a02323ebd64433cbaead5def499861Satoshi Kataoka 140feec20a692c9ffdecf7855a45531a12f129086caSatoshi Kataoka mTouchPositionCorrectionEnabled = mSampledInputSize > 0 && mHasTouchPositionCorrectionData 1410edab9d2fcc30667c79aa9221dbb27f042d8b455Satoshi Kataoka && xCoordinates && yCoordinates; 14208f00cf55f2e083c1ed254a32495b622c9ad9862Satoshi Kataoka if (!isGeometric && pointerId == 0) { 143d7a8fbf6a9ec8828d4b6d1c615a6c605bbe5b72eSatoshi Kataoka ProximityInfoStateUtils::initPrimaryInputWord( 144d7a8fbf6a9ec8828d4b6d1c615a6c605bbe5b72eSatoshi Kataoka inputSize, mInputProximities, mPrimaryInputWord); 145d7a8fbf6a9ec8828d4b6d1c615a6c605bbe5b72eSatoshi Kataoka if (mTouchPositionCorrectionEnabled) { 146d7a8fbf6a9ec8828d4b6d1c615a6c605bbe5b72eSatoshi Kataoka ProximityInfoStateUtils::initNormalizedSquaredDistances( 147d7a8fbf6a9ec8828d4b6d1c615a6c605bbe5b72eSatoshi Kataoka mProximityInfo, inputSize, xCoordinates, yCoordinates, mInputProximities, 14820b6775acc957896bdb038dfd99794d6cd7cea5aSatoshi Kataoka &mSampledInputXs, &mSampledInputYs, mNormalizedSquaredDistances); 1493e8c58f68d53e6cc9dbf59201c7bdfb8ad04a1cdSatoshi Kataoka } 1503e8c58f68d53e6cc9dbf59201c7bdfb8ad04a1cdSatoshi Kataoka } 151952ec4977d772607140773ae7d8868f86a7e0097Satoshi Kataoka if (DEBUG_GEO_FULL) { 152feec20a692c9ffdecf7855a45531a12f129086caSatoshi Kataoka AKLOGI("ProximityState init finished: %d points out of %d", mSampledInputSize, inputSize); 153feec20a692c9ffdecf7855a45531a12f129086caSatoshi Kataoka } 154feec20a692c9ffdecf7855a45531a12f129086caSatoshi Kataoka} 155feec20a692c9ffdecf7855a45531a12f129086caSatoshi Kataoka 1560519fdd18ac4414b8298d3338db1c8ccce032170Satoshi Kataoka// TODO: Remove the "scale" parameter 1570519fdd18ac4414b8298d3338db1c8ccce032170Satoshi Kataoka// This function basically converts from a length to an edit distance. Accordingly, it's obviously 1580519fdd18ac4414b8298d3338db1c8ccce032170Satoshi Kataoka// wrong to compare with mMaxPointToKeyLength. 1590519fdd18ac4414b8298d3338db1c8ccce032170Satoshi Kataokafloat ProximityInfoState::getPointToKeyLength( 1600519fdd18ac4414b8298d3338db1c8ccce032170Satoshi Kataoka const int inputIndex, const int codePoint, const float scale) const { 161ff74cc3e5e75fc0c6b9ffaa5e68d879775dc6115Keisuke Kuroyanagi const int keyId = mProximityInfo->getKeyIndexOf(codePoint); 162ff74cc3e5e75fc0c6b9ffaa5e68d879775dc6115Keisuke Kuroyanagi if (keyId != NOT_AN_INDEX) { 163ff74cc3e5e75fc0c6b9ffaa5e68d879775dc6115Keisuke Kuroyanagi const int index = inputIndex * mProximityInfo->getKeyCount() + keyId; 164e5aad5646309e80e1cd71533fb47a6be43f3aa2fSatoshi Kataoka return min(mSampledDistanceCache_G[index] * scale, mMaxPointToKeyLength); 165ff74cc3e5e75fc0c6b9ffaa5e68d879775dc6115Keisuke Kuroyanagi } 1661e61493c50082264caaef862df02b1ccc84dc396Ken Wakasa if (isSkippableCodePoint(codePoint)) { 167806eba452423e5e5971ef096dfae3fed180db665Keisuke Kuroyanagi return 0.0f; 168806eba452423e5e5971ef096dfae3fed180db665Keisuke Kuroyanagi } 169ff74cc3e5e75fc0c6b9ffaa5e68d879775dc6115Keisuke Kuroyanagi // If the char is not a key on the keyboard then return the max length. 170ff74cc3e5e75fc0c6b9ffaa5e68d879775dc6115Keisuke Kuroyanagi return MAX_POINT_TO_KEY_LENGTH; 171806eba452423e5e5971ef096dfae3fed180db665Keisuke Kuroyanagi} 172806eba452423e5e5971ef096dfae3fed180db665Keisuke Kuroyanagi 173a9763f93d76f97b9c6ed7dd1369a4d8cb016f06fSatoshi Kataokafloat ProximityInfoState::getPointToKeyLength_G(const int inputIndex, const int codePoint) const { 1740519fdd18ac4414b8298d3338db1c8ccce032170Satoshi Kataoka return getPointToKeyLength(inputIndex, codePoint, 1.0f); 1750519fdd18ac4414b8298d3338db1c8ccce032170Satoshi Kataoka} 1760519fdd18ac4414b8298d3338db1c8ccce032170Satoshi Kataoka 1770519fdd18ac4414b8298d3338db1c8ccce032170Satoshi Kataoka// TODO: Remove the "scale" parameter 1780519fdd18ac4414b8298d3338db1c8ccce032170Satoshi Kataokafloat ProximityInfoState::getPointToKeyByIdLength( 1790519fdd18ac4414b8298d3338db1c8ccce032170Satoshi Kataoka const int inputIndex, const int keyId, const float scale) const { 180d4828d5053ac30476b884c177235be0cac982c92Satoshi Kataoka return ProximityInfoStateUtils::getPointToKeyByIdLength(mMaxPointToKeyLength, 181e5aad5646309e80e1cd71533fb47a6be43f3aa2fSatoshi Kataoka &mSampledDistanceCache_G, mProximityInfo->getKeyCount(), inputIndex, keyId, scale); 182687a244703a02323ebd64433cbaead5def499861Satoshi Kataoka} 183687a244703a02323ebd64433cbaead5def499861Satoshi Kataoka 1840519fdd18ac4414b8298d3338db1c8ccce032170Satoshi Kataokafloat ProximityInfoState::getPointToKeyByIdLength(const int inputIndex, const int keyId) const { 1850519fdd18ac4414b8298d3338db1c8ccce032170Satoshi Kataoka return getPointToKeyByIdLength(inputIndex, keyId, 1.0f); 1860519fdd18ac4414b8298d3338db1c8ccce032170Satoshi Kataoka} 1870519fdd18ac4414b8298d3338db1c8ccce032170Satoshi Kataoka 1882c2f3a90d8115777adbe9ffd597f344aede84276Ken Wakasa// In the following function, c is the current character of the dictionary word currently examined. 1892c2f3a90d8115777adbe9ffd597f344aede84276Ken Wakasa// currentChars is an array containing the keys close to the character the user actually typed at 1902c2f3a90d8115777adbe9ffd597f344aede84276Ken Wakasa// the same position. We want to see if c is in it: if so, then the word contains at that position 1912c2f3a90d8115777adbe9ffd597f344aede84276Ken Wakasa// a character close to what the user typed. 1922c2f3a90d8115777adbe9ffd597f344aede84276Ken Wakasa// What the user typed is actually the first character of the array. 1932c2f3a90d8115777adbe9ffd597f344aede84276Ken Wakasa// proximityIndex is a pointer to the variable where getMatchedProximityId returns the index of c 1942c2f3a90d8115777adbe9ffd597f344aede84276Ken Wakasa// in the proximity chars of the input index. 1952c2f3a90d8115777adbe9ffd597f344aede84276Ken Wakasa// Notice : accented characters do not have a proximity list, so they are alone in their list. The 1962c2f3a90d8115777adbe9ffd597f344aede84276Ken Wakasa// non-accented version of the character should be considered "close", but not the other keys close 1972c2f3a90d8115777adbe9ffd597f344aede84276Ken Wakasa// to the non-accented version. 1982c2f3a90d8115777adbe9ffd597f344aede84276Ken WakasaProximityType ProximityInfoState::getMatchedProximityId(const int index, const int c, 1992c2f3a90d8115777adbe9ffd597f344aede84276Ken Wakasa const bool checkProximityChars, int *proximityIndex) const { 2002c2f3a90d8115777adbe9ffd597f344aede84276Ken Wakasa const int *currentCodePoints = getProximityCodePointsAt(index); 2012c2f3a90d8115777adbe9ffd597f344aede84276Ken Wakasa const int firstCodePoint = currentCodePoints[0]; 2022c2f3a90d8115777adbe9ffd597f344aede84276Ken Wakasa const int baseLowerC = toBaseLowerCase(c); 2032c2f3a90d8115777adbe9ffd597f344aede84276Ken Wakasa 2042c2f3a90d8115777adbe9ffd597f344aede84276Ken Wakasa // The first char in the array is what user typed. If it matches right away, that means the 2052c2f3a90d8115777adbe9ffd597f344aede84276Ken Wakasa // user typed that same char for this pos. 2062c2f3a90d8115777adbe9ffd597f344aede84276Ken Wakasa if (firstCodePoint == baseLowerC || firstCodePoint == c) { 2072c2f3a90d8115777adbe9ffd597f344aede84276Ken Wakasa return EQUIVALENT_CHAR; 2082c2f3a90d8115777adbe9ffd597f344aede84276Ken Wakasa } 2092c2f3a90d8115777adbe9ffd597f344aede84276Ken Wakasa 2102c2f3a90d8115777adbe9ffd597f344aede84276Ken Wakasa if (!checkProximityChars) return UNRELATED_CHAR; 2112c2f3a90d8115777adbe9ffd597f344aede84276Ken Wakasa 2122c2f3a90d8115777adbe9ffd597f344aede84276Ken Wakasa // If the non-accented, lowercased version of that first character matches c, then we have a 2132c2f3a90d8115777adbe9ffd597f344aede84276Ken Wakasa // non-accented version of the accented character the user typed. Treat it as a close char. 2142c2f3a90d8115777adbe9ffd597f344aede84276Ken Wakasa if (toBaseLowerCase(firstCodePoint) == baseLowerC) { 2152c2f3a90d8115777adbe9ffd597f344aede84276Ken Wakasa return NEAR_PROXIMITY_CHAR; 2162c2f3a90d8115777adbe9ffd597f344aede84276Ken Wakasa } 2172c2f3a90d8115777adbe9ffd597f344aede84276Ken Wakasa 2182c2f3a90d8115777adbe9ffd597f344aede84276Ken Wakasa // Not an exact nor an accent-alike match: search the list of close keys 2192c2f3a90d8115777adbe9ffd597f344aede84276Ken Wakasa int j = 1; 2206c22439bf80da08576e86c1282afc5cfa431e235Ken Wakasa while (j < MAX_PROXIMITY_CHARS_SIZE 2212c2f3a90d8115777adbe9ffd597f344aede84276Ken Wakasa && currentCodePoints[j] > ADDITIONAL_PROXIMITY_CHAR_DELIMITER_CODE) { 2222c2f3a90d8115777adbe9ffd597f344aede84276Ken Wakasa const bool matched = (currentCodePoints[j] == baseLowerC || currentCodePoints[j] == c); 2232c2f3a90d8115777adbe9ffd597f344aede84276Ken Wakasa if (matched) { 2242c2f3a90d8115777adbe9ffd597f344aede84276Ken Wakasa if (proximityIndex) { 2252c2f3a90d8115777adbe9ffd597f344aede84276Ken Wakasa *proximityIndex = j; 2262c2f3a90d8115777adbe9ffd597f344aede84276Ken Wakasa } 2272c2f3a90d8115777adbe9ffd597f344aede84276Ken Wakasa return NEAR_PROXIMITY_CHAR; 2282c2f3a90d8115777adbe9ffd597f344aede84276Ken Wakasa } 2292c2f3a90d8115777adbe9ffd597f344aede84276Ken Wakasa ++j; 2302c2f3a90d8115777adbe9ffd597f344aede84276Ken Wakasa } 2316c22439bf80da08576e86c1282afc5cfa431e235Ken Wakasa if (j < MAX_PROXIMITY_CHARS_SIZE 2322c2f3a90d8115777adbe9ffd597f344aede84276Ken Wakasa && currentCodePoints[j] == ADDITIONAL_PROXIMITY_CHAR_DELIMITER_CODE) { 2332c2f3a90d8115777adbe9ffd597f344aede84276Ken Wakasa ++j; 2346c22439bf80da08576e86c1282afc5cfa431e235Ken Wakasa while (j < MAX_PROXIMITY_CHARS_SIZE 2352c2f3a90d8115777adbe9ffd597f344aede84276Ken Wakasa && currentCodePoints[j] > ADDITIONAL_PROXIMITY_CHAR_DELIMITER_CODE) { 2362c2f3a90d8115777adbe9ffd597f344aede84276Ken Wakasa const bool matched = (currentCodePoints[j] == baseLowerC || currentCodePoints[j] == c); 2372c2f3a90d8115777adbe9ffd597f344aede84276Ken Wakasa if (matched) { 2382c2f3a90d8115777adbe9ffd597f344aede84276Ken Wakasa if (proximityIndex) { 2392c2f3a90d8115777adbe9ffd597f344aede84276Ken Wakasa *proximityIndex = j; 2402c2f3a90d8115777adbe9ffd597f344aede84276Ken Wakasa } 2412c2f3a90d8115777adbe9ffd597f344aede84276Ken Wakasa return ADDITIONAL_PROXIMITY_CHAR; 2422c2f3a90d8115777adbe9ffd597f344aede84276Ken Wakasa } 2432c2f3a90d8115777adbe9ffd597f344aede84276Ken Wakasa ++j; 2442c2f3a90d8115777adbe9ffd597f344aede84276Ken Wakasa } 2452c2f3a90d8115777adbe9ffd597f344aede84276Ken Wakasa } 2462c2f3a90d8115777adbe9ffd597f344aede84276Ken Wakasa // Was not included, signal this as an unrelated character. 2472c2f3a90d8115777adbe9ffd597f344aede84276Ken Wakasa return UNRELATED_CHAR; 2482c2f3a90d8115777adbe9ffd597f344aede84276Ken Wakasa} 2492c2f3a90d8115777adbe9ffd597f344aede84276Ken Wakasa 250ff74cc3e5e75fc0c6b9ffaa5e68d879775dc6115Keisuke Kuroyanagibool ProximityInfoState::isKeyInSerchKeysAfterIndex(const int index, const int keyId) const { 25120b6775acc957896bdb038dfd99794d6cd7cea5aSatoshi Kataoka ASSERT(keyId >= 0 && index >= 0 && index < mSampledInputSize); 252e5cdd21102e4e49b18c696261a084783eb6d7e7aSatoshi Kataoka return mSampledSearchKeySets[index].test(keyId); 253ff74cc3e5e75fc0c6b9ffaa5e68d879775dc6115Keisuke Kuroyanagi} 254ff74cc3e5e75fc0c6b9ffaa5e68d879775dc6115Keisuke Kuroyanagi 255ff74cc3e5e75fc0c6b9ffaa5e68d879775dc6115Keisuke Kuroyanagifloat ProximityInfoState::getDirection(const int index0, const int index1) const { 256ee62b78c9675bddaf2437e0cf521f6115e1d9febSatoshi Kataoka return ProximityInfoStateUtils::getDirection( 257ee62b78c9675bddaf2437e0cf521f6115e1d9febSatoshi Kataoka &mSampledInputXs, &mSampledInputYs, index0, index1); 258ff74cc3e5e75fc0c6b9ffaa5e68d879775dc6115Keisuke Kuroyanagi} 259ff74cc3e5e75fc0c6b9ffaa5e68d879775dc6115Keisuke Kuroyanagi 260ff74cc3e5e75fc0c6b9ffaa5e68d879775dc6115Keisuke Kuroyanagifloat ProximityInfoState::getLineToKeyDistance( 261ff74cc3e5e75fc0c6b9ffaa5e68d879775dc6115Keisuke Kuroyanagi const int from, const int to, const int keyId, const bool extend) const { 262feec20a692c9ffdecf7855a45531a12f129086caSatoshi Kataoka if (from < 0 || from > mSampledInputSize - 1) { 263ff74cc3e5e75fc0c6b9ffaa5e68d879775dc6115Keisuke Kuroyanagi return 0.0f; 264ff74cc3e5e75fc0c6b9ffaa5e68d879775dc6115Keisuke Kuroyanagi } 265feec20a692c9ffdecf7855a45531a12f129086caSatoshi Kataoka if (to < 0 || to > mSampledInputSize - 1) { 266ff74cc3e5e75fc0c6b9ffaa5e68d879775dc6115Keisuke Kuroyanagi return 0.0f; 267ff74cc3e5e75fc0c6b9ffaa5e68d879775dc6115Keisuke Kuroyanagi } 268feec20a692c9ffdecf7855a45531a12f129086caSatoshi Kataoka const int x0 = mSampledInputXs[from]; 269feec20a692c9ffdecf7855a45531a12f129086caSatoshi Kataoka const int y0 = mSampledInputYs[from]; 270feec20a692c9ffdecf7855a45531a12f129086caSatoshi Kataoka const int x1 = mSampledInputXs[to]; 271feec20a692c9ffdecf7855a45531a12f129086caSatoshi Kataoka const int y1 = mSampledInputYs[to]; 272ff74cc3e5e75fc0c6b9ffaa5e68d879775dc6115Keisuke Kuroyanagi 273ff74cc3e5e75fc0c6b9ffaa5e68d879775dc6115Keisuke Kuroyanagi const int keyX = mProximityInfo->getKeyCenterXOfKeyIdG(keyId); 274ff74cc3e5e75fc0c6b9ffaa5e68d879775dc6115Keisuke Kuroyanagi const int keyY = mProximityInfo->getKeyCenterYOfKeyIdG(keyId); 275ff74cc3e5e75fc0c6b9ffaa5e68d879775dc6115Keisuke Kuroyanagi 2760c2227ab991774768414d8ea60a469f005eb9f1aKen Wakasa return ProximityInfoUtils::pointToLineSegSquaredDistanceFloat( 2770c2227ab991774768414d8ea60a469f005eb9f1aKen Wakasa keyX, keyY, x0, y0, x1, y1, extend); 278806eba452423e5e5971ef096dfae3fed180db665Keisuke Kuroyanagi} 279806eba452423e5e5971ef096dfae3fed180db665Keisuke Kuroyanagi 280e0349619acdba79223390c9925d81f7e88c7f8adSatoshi Kataokafloat ProximityInfoState::getMostProbableString(int *const codePointBuf) const { 28120b6775acc957896bdb038dfd99794d6cd7cea5aSatoshi Kataoka memcpy(codePointBuf, mMostProbableString, sizeof(mMostProbableString)); 28220b6775acc957896bdb038dfd99794d6cd7cea5aSatoshi Kataoka return mMostProbableStringProbability; 283ff74cc3e5e75fc0c6b9ffaa5e68d879775dc6115Keisuke Kuroyanagi} 284ff74cc3e5e75fc0c6b9ffaa5e68d879775dc6115Keisuke Kuroyanagi 285f32869c6b6296a8bf594abdf0b18281d9312e54fSatoshi Kataokabool ProximityInfoState::hasSpaceProximity(const int index) const { 286f32869c6b6296a8bf594abdf0b18281d9312e54fSatoshi Kataoka ASSERT(0 <= index && index < mSampledInputSize); 287f32869c6b6296a8bf594abdf0b18281d9312e54fSatoshi Kataoka return mProximityInfo->hasSpaceProximity(getInputX(index), getInputY(index)); 288f32869c6b6296a8bf594abdf0b18281d9312e54fSatoshi Kataoka} 289f32869c6b6296a8bf594abdf0b18281d9312e54fSatoshi Kataoka 290ff74cc3e5e75fc0c6b9ffaa5e68d879775dc6115Keisuke Kuroyanagi// Returns a probability of mapping index to keyIndex. 291ff74cc3e5e75fc0c6b9ffaa5e68d879775dc6115Keisuke Kuroyanagifloat ProximityInfoState::getProbability(const int index, const int keyIndex) const { 292feec20a692c9ffdecf7855a45531a12f129086caSatoshi Kataoka ASSERT(0 <= index && index < mSampledInputSize); 293ff74cc3e5e75fc0c6b9ffaa5e68d879775dc6115Keisuke Kuroyanagi hash_map_compat<int, float>::const_iterator it = mCharProbabilities[index].find(keyIndex); 294ff74cc3e5e75fc0c6b9ffaa5e68d879775dc6115Keisuke Kuroyanagi if (it != mCharProbabilities[index].end()) { 295ff74cc3e5e75fc0c6b9ffaa5e68d879775dc6115Keisuke Kuroyanagi return it->second; 296ff74cc3e5e75fc0c6b9ffaa5e68d879775dc6115Keisuke Kuroyanagi } 297ff74cc3e5e75fc0c6b9ffaa5e68d879775dc6115Keisuke Kuroyanagi return static_cast<float>(MAX_POINT_TO_KEY_LENGTH); 298806eba452423e5e5971ef096dfae3fed180db665Keisuke Kuroyanagi} 2993e8c58f68d53e6cc9dbf59201c7bdfb8ad04a1cdSatoshi Kataoka} // namespace latinime 300