Home | History | Annotate | Download | only in src
      1 /*
      2  * Copyright (C) 2012 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 #ifndef LATINIME_PROXIMITY_INFO_STATE_H
     18 #define LATINIME_PROXIMITY_INFO_STATE_H
     19 
     20 #include <cstring> // for memset()
     21 #include <vector>
     22 
     23 #include "char_utils.h"
     24 #include "defines.h"
     25 #include "hash_map_compat.h"
     26 #include "proximity_info_params.h"
     27 #include "proximity_info_state_utils.h"
     28 
     29 namespace latinime {
     30 
     31 class ProximityInfo;
     32 
     33 class ProximityInfoState {
     34  public:
     35     /////////////////////////////////////////
     36     // Defined in proximity_info_state.cpp //
     37     /////////////////////////////////////////
     38     void initInputParams(const int pointerId, const float maxPointToKeyLength,
     39             const ProximityInfo *proximityInfo, const int *const inputCodes,
     40             const int inputSize, const int *xCoordinates, const int *yCoordinates,
     41             const int *const times, const int *const pointerIds, const bool isGeometric);
     42 
     43     /////////////////////////////////////////
     44     // Defined here                        //
     45     /////////////////////////////////////////
     46     AK_FORCE_INLINE ProximityInfoState()
     47             : mProximityInfo(0), mMaxPointToKeyLength(0.0f), mAverageSpeed(0.0f),
     48               mHasTouchPositionCorrectionData(false), mMostCommonKeyWidthSquare(0),
     49               mKeyCount(0), mCellHeight(0), mCellWidth(0), mGridHeight(0), mGridWidth(0),
     50               mIsContinuousSuggestionPossible(false), mSampledInputXs(), mSampledInputYs(),
     51               mSampledTimes(), mSampledInputIndice(), mSampledLengthCache(),
     52               mBeelineSpeedPercentiles(), mSampledNormalizedSquaredLengthCache(), mSpeedRates(),
     53               mDirections(), mCharProbabilities(), mSampledNearKeySets(), mSampledSearchKeySets(),
     54               mSampledSearchKeyVectors(), mTouchPositionCorrectionEnabled(false),
     55               mSampledInputSize(0), mMostProbableStringProbability(0.0f) {
     56         memset(mInputProximities, 0, sizeof(mInputProximities));
     57         memset(mNormalizedSquaredDistances, 0, sizeof(mNormalizedSquaredDistances));
     58         memset(mPrimaryInputWord, 0, sizeof(mPrimaryInputWord));
     59         memset(mMostProbableString, 0, sizeof(mMostProbableString));
     60     }
     61 
     62     // Non virtual inline destructor -- never inherit this class
     63     AK_FORCE_INLINE ~ProximityInfoState() {}
     64 
     65     inline int getPrimaryCodePointAt(const int index) const {
     66         return getProximityCodePointsAt(index)[0];
     67     }
     68 
     69     inline bool sameAsTyped(const int *word, int length) const {
     70         if (length != mSampledInputSize) {
     71             return false;
     72         }
     73         const int *inputProximities = mInputProximities;
     74         while (length--) {
     75             if (*inputProximities != *word) {
     76                 return false;
     77             }
     78             inputProximities += MAX_PROXIMITY_CHARS_SIZE;
     79             word++;
     80         }
     81         return true;
     82     }
     83 
     84     AK_FORCE_INLINE bool existsCodePointInProximityAt(const int index, const int c) const {
     85         const int *codePoints = getProximityCodePointsAt(index);
     86         int i = 0;
     87         while (codePoints[i] > 0 && i < MAX_PROXIMITY_CHARS_SIZE) {
     88             if (codePoints[i++] == c) {
     89                 return true;
     90             }
     91         }
     92         return false;
     93     }
     94 
     95     inline bool existsAdjacentProximityChars(const int index) const {
     96         if (index < 0 || index >= mSampledInputSize) return false;
     97         const int currentCodePoint = getPrimaryCodePointAt(index);
     98         const int leftIndex = index - 1;
     99         if (leftIndex >= 0 && existsCodePointInProximityAt(leftIndex, currentCodePoint)) {
    100             return true;
    101         }
    102         const int rightIndex = index + 1;
    103         if (rightIndex < mSampledInputSize
    104                 && existsCodePointInProximityAt(rightIndex, currentCodePoint)) {
    105             return true;
    106         }
    107         return false;
    108     }
    109 
    110     inline int getNormalizedSquaredDistance(
    111             const int inputIndex, const int proximityIndex) const {
    112         return mNormalizedSquaredDistances[
    113                 inputIndex * MAX_PROXIMITY_CHARS_SIZE + proximityIndex];
    114     }
    115 
    116     inline const int *getPrimaryInputWord() const {
    117         return mPrimaryInputWord;
    118     }
    119 
    120     inline bool touchPositionCorrectionEnabled() const {
    121         return mTouchPositionCorrectionEnabled;
    122     }
    123 
    124     bool isUsed() const {
    125         return mSampledInputSize > 0;
    126     }
    127 
    128     int size() const {
    129         return mSampledInputSize;
    130     }
    131 
    132     int getInputX(const int index) const {
    133         return mSampledInputXs[index];
    134     }
    135 
    136     int getInputY(const int index) const {
    137         return mSampledInputYs[index];
    138     }
    139 
    140     bool hasSpaceProximity(const int index) const;
    141 
    142     int getLengthCache(const int index) const {
    143         return mSampledLengthCache[index];
    144     }
    145 
    146     bool isContinuousSuggestionPossible() const {
    147         return mIsContinuousSuggestionPossible;
    148     }
    149 
    150     // TODO: Rename s/Length/NormalizedSquaredLength/
    151     float getPointToKeyByIdLength(const int inputIndex, const int keyId) const;
    152     // TODO: Rename s/Length/NormalizedSquaredLength/
    153     float getPointToKeyLength(const int inputIndex, const int codePoint) const;
    154 
    155     ProximityType getProximityType(const int index, const int codePoint,
    156             const bool checkProximityChars, int *proximityIndex = 0) const;
    157 
    158     ProximityType getProximityTypeG(const int index, const int codePoint) const;
    159 
    160     const std::vector<int> *getSearchKeyVector(const int index) const {
    161         return &mSampledSearchKeyVectors[index];
    162     }
    163 
    164     float getSpeedRate(const int index) const {
    165         return mSpeedRates[index];
    166     }
    167 
    168     AK_FORCE_INLINE int getBeelineSpeedPercentile(const int id) const {
    169         return mBeelineSpeedPercentiles[id];
    170     }
    171 
    172     AK_FORCE_INLINE DoubleLetterLevel getDoubleLetterLevel(const int id) const {
    173         const int beelineSpeedRate = getBeelineSpeedPercentile(id);
    174         if (beelineSpeedRate == 0) {
    175             return A_STRONG_DOUBLE_LETTER;
    176         } else if (beelineSpeedRate
    177                 < ProximityInfoParams::MIN_DOUBLE_LETTER_BEELINE_SPEED_PERCENTILE) {
    178             return A_DOUBLE_LETTER;
    179         } else {
    180             return NOT_A_DOUBLE_LETTER;
    181         }
    182     }
    183 
    184     float getDirection(const int index) const {
    185         return mDirections[index];
    186     }
    187     // get xy direction
    188     float getDirection(const int x, const int y) const;
    189 
    190     float getMostProbableString(int *const codePointBuf) const;
    191 
    192     float getProbability(const int index, const int charCode) const;
    193 
    194     float getLineToKeyDistance(
    195             const int from, const int to, const int keyId, const bool extend) const;
    196 
    197     bool isKeyInSerchKeysAfterIndex(const int index, const int keyId) const;
    198 
    199  private:
    200     DISALLOW_COPY_AND_ASSIGN(ProximityInfoState);
    201     /////////////////////////////////////////
    202     // Defined in proximity_info_state.cpp //
    203     /////////////////////////////////////////
    204     float calculateNormalizedSquaredDistance(const int keyIndex, const int inputIndex) const;
    205 
    206     float calculateSquaredDistanceFromSweetSpotCenter(
    207             const int keyIndex, const int inputIndex) const;
    208 
    209     /////////////////////////////////////////
    210     // Defined here                        //
    211     /////////////////////////////////////////
    212 
    213     inline const int *getProximityCodePointsAt(const int index) const {
    214         return ProximityInfoStateUtils::getProximityCodePointsAt(mInputProximities, index);
    215     }
    216 
    217     // const
    218     const ProximityInfo *mProximityInfo;
    219     float mMaxPointToKeyLength;
    220     float mAverageSpeed;
    221     bool mHasTouchPositionCorrectionData;
    222     int mMostCommonKeyWidthSquare;
    223     int mKeyCount;
    224     int mCellHeight;
    225     int mCellWidth;
    226     int mGridHeight;
    227     int mGridWidth;
    228     bool mIsContinuousSuggestionPossible;
    229 
    230     std::vector<int> mSampledInputXs;
    231     std::vector<int> mSampledInputYs;
    232     std::vector<int> mSampledTimes;
    233     std::vector<int> mSampledInputIndice;
    234     std::vector<int> mSampledLengthCache;
    235     std::vector<int> mBeelineSpeedPercentiles;
    236     std::vector<float> mSampledNormalizedSquaredLengthCache;
    237     std::vector<float> mSpeedRates;
    238     std::vector<float> mDirections;
    239     // probabilities of skipping or mapping to a key for each point.
    240     std::vector<hash_map_compat<int, float> > mCharProbabilities;
    241     // The vector for the key code set which holds nearby keys for each sampled input point
    242     // 1. Used to calculate the probability of the key
    243     // 2. Used to calculate mSampledSearchKeySets
    244     std::vector<ProximityInfoStateUtils::NearKeycodesSet> mSampledNearKeySets;
    245     // The vector for the key code set which holds nearby keys of some trailing sampled input points
    246     // for each sampled input point. These nearby keys contain the next characters which can be in
    247     // the dictionary. Specifically, currently we are looking for keys nearby trailing sampled
    248     // inputs including the current input point.
    249     std::vector<ProximityInfoStateUtils::NearKeycodesSet> mSampledSearchKeySets;
    250     std::vector<std::vector<int> > mSampledSearchKeyVectors;
    251     bool mTouchPositionCorrectionEnabled;
    252     int mInputProximities[MAX_PROXIMITY_CHARS_SIZE * MAX_WORD_LENGTH];
    253     int mNormalizedSquaredDistances[MAX_PROXIMITY_CHARS_SIZE * MAX_WORD_LENGTH];
    254     int mSampledInputSize;
    255     int mPrimaryInputWord[MAX_WORD_LENGTH];
    256     float mMostProbableStringProbability;
    257     int mMostProbableString[MAX_WORD_LENGTH];
    258 };
    259 } // namespace latinime
    260 #endif // LATINIME_PROXIMITY_INFO_STATE_H
    261