18fbd55229243cb66c03d5ea1f79dfb39f596590dsatok/*
28fbd55229243cb66c03d5ea1f79dfb39f596590dsatok * Copyright (C) 2011 The Android Open Source Project
38fbd55229243cb66c03d5ea1f79dfb39f596590dsatok *
48fbd55229243cb66c03d5ea1f79dfb39f596590dsatok * Licensed under the Apache License, Version 2.0 (the "License");
58fbd55229243cb66c03d5ea1f79dfb39f596590dsatok * you may not use this file except in compliance with the License.
68fbd55229243cb66c03d5ea1f79dfb39f596590dsatok * You may obtain a copy of the License at
78fbd55229243cb66c03d5ea1f79dfb39f596590dsatok *
88fbd55229243cb66c03d5ea1f79dfb39f596590dsatok *      http://www.apache.org/licenses/LICENSE-2.0
98fbd55229243cb66c03d5ea1f79dfb39f596590dsatok *
108fbd55229243cb66c03d5ea1f79dfb39f596590dsatok * Unless required by applicable law or agreed to in writing, software
118fbd55229243cb66c03d5ea1f79dfb39f596590dsatok * distributed under the License is distributed on an "AS IS" BASIS,
128fbd55229243cb66c03d5ea1f79dfb39f596590dsatok * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
138fbd55229243cb66c03d5ea1f79dfb39f596590dsatok * See the License for the specific language governing permissions and
148fbd55229243cb66c03d5ea1f79dfb39f596590dsatok * limitations under the License.
158fbd55229243cb66c03d5ea1f79dfb39f596590dsatok */
168fbd55229243cb66c03d5ea1f79dfb39f596590dsatok
178fbd55229243cb66c03d5ea1f79dfb39f596590dsatok#ifndef LATINIME_PROXIMITY_INFO_H
188fbd55229243cb66c03d5ea1f79dfb39f596590dsatok#define LATINIME_PROXIMITY_INFO_H
198fbd55229243cb66c03d5ea1f79dfb39f596590dsatok
208fbd55229243cb66c03d5ea1f79dfb39f596590dsatok#include <stdint.h>
218fbd55229243cb66c03d5ea1f79dfb39f596590dsatok
228fbd55229243cb66c03d5ea1f79dfb39f596590dsatok#include "defines.h"
23132168519e1d681ea1b8fd7fcf283155a0b3997eTom Ouyang#include "hash_map_compat.h"
24bb005f787f4e00bd832e6a78797be10af2994061Ken Wakasa#include "jni.h"
258fbd55229243cb66c03d5ea1f79dfb39f596590dsatok
268fbd55229243cb66c03d5ea1f79dfb39f596590dsatoknamespace latinime {
278fbd55229243cb66c03d5ea1f79dfb39f596590dsatok
28cfca3c6317143ce68770cab02eb7d7a5dc8765c9satokclass Correction;
292df3060883c7535029c7dfbbb4f7b05935d796aesatok
308fbd55229243cb66c03d5ea1f79dfb39f596590dsatokclass ProximityInfo {
31e12e9b5b69e6242af61ee690a81bedde1bdd4936Ken Wakasa public:
32015114592460cca82e5196f2c2e2eff23f9d97aeKen Wakasa    ProximityInfo(JNIEnv *env, const jstring localeJStr, const int maxProximityCharsSize,
33a58ebc73ae3eb2783713c471d8abb348c7dfc8daTadashi G. Takaoka            const int keyboardWidth, const int keyboardHeight, const int gridWidth,
34bb005f787f4e00bd832e6a78797be10af2994061Ken Wakasa            const int gridHeight, const int mostCommonKeyWidth, const jintArray proximityChars,
35bb005f787f4e00bd832e6a78797be10af2994061Ken Wakasa            const int keyCount, const jintArray keyXCoordinates, const jintArray keyYCoordinates,
36bb005f787f4e00bd832e6a78797be10af2994061Ken Wakasa            const jintArray keyWidths, const jintArray keyHeights, const jintArray keyCharCodes,
37bb005f787f4e00bd832e6a78797be10af2994061Ken Wakasa            const jfloatArray sweetSpotCenterXs, const jfloatArray sweetSpotCenterYs,
38bb005f787f4e00bd832e6a78797be10af2994061Ken Wakasa            const jfloatArray sweetSpotRadii);
398fbd55229243cb66c03d5ea1f79dfb39f596590dsatok    ~ProximityInfo();
40817e517e463cb32726ff5a62196ac8744848e29bsatok    bool hasSpaceProximity(const int x, const int y) const;
413e8c58f68d53e6cc9dbf59201c7bdfb8ad04a1cdSatoshi Kataoka    int getNormalizedSquaredDistance(const int inputIndex, const int proximityIndex) const;
420edab9d2fcc30667c79aa9221dbb27f042d8b455Satoshi Kataoka    float getNormalizedSquaredDistanceFromCenterFloatG(
43e7398cdb2b48eb52dc9676c8efa75bc7cb9af3e9Satoshi Kataoka            const int keyId, const int x, const int y) const;
443e8c58f68d53e6cc9dbf59201c7bdfb8ad04a1cdSatoshi Kataoka    bool sameAsTyped(const unsigned short *word, int length) const;
45f2789819bd005b5b0581e8439601b5501306327dKen Wakasa    int getKeyIndexOf(const int c) const;
46f2789819bd005b5b0581e8439601b5501306327dKen Wakasa    int getCodePointOf(const int keyIndex) const;
473e8c58f68d53e6cc9dbf59201c7bdfb8ad04a1cdSatoshi Kataoka    bool hasSweetSpotData(const int keyIndex) const {
483e8c58f68d53e6cc9dbf59201c7bdfb8ad04a1cdSatoshi Kataoka        // When there are no calibration data for a key,
493e8c58f68d53e6cc9dbf59201c7bdfb8ad04a1cdSatoshi Kataoka        // the radius of the key is assigned to zero.
50fee0ac60b1cd0a4760ca8f310ff8a86b925d833bKen Wakasa        return mSweetSpotRadii[keyIndex] > 0.0f;
513e8c58f68d53e6cc9dbf59201c7bdfb8ad04a1cdSatoshi Kataoka    }
523e8c58f68d53e6cc9dbf59201c7bdfb8ad04a1cdSatoshi Kataoka    float getSweetSpotRadiiAt(int keyIndex) const {
533e8c58f68d53e6cc9dbf59201c7bdfb8ad04a1cdSatoshi Kataoka        return mSweetSpotRadii[keyIndex];
543e8c58f68d53e6cc9dbf59201c7bdfb8ad04a1cdSatoshi Kataoka    }
553e8c58f68d53e6cc9dbf59201c7bdfb8ad04a1cdSatoshi Kataoka    float getSweetSpotCenterXAt(int keyIndex) const {
563e8c58f68d53e6cc9dbf59201c7bdfb8ad04a1cdSatoshi Kataoka        return mSweetSpotCenterXs[keyIndex];
573e8c58f68d53e6cc9dbf59201c7bdfb8ad04a1cdSatoshi Kataoka    }
583e8c58f68d53e6cc9dbf59201c7bdfb8ad04a1cdSatoshi Kataoka    float getSweetSpotCenterYAt(int keyIndex) const {
593e8c58f68d53e6cc9dbf59201c7bdfb8ad04a1cdSatoshi Kataoka        return mSweetSpotCenterYs[keyIndex];
603e8c58f68d53e6cc9dbf59201c7bdfb8ad04a1cdSatoshi Kataoka    }
613e8c58f68d53e6cc9dbf59201c7bdfb8ad04a1cdSatoshi Kataoka    void calculateNearbyKeyCodes(
623e8c58f68d53e6cc9dbf59201c7bdfb8ad04a1cdSatoshi Kataoka            const int x, const int y, const int32_t primaryKey, int *inputCodes) const;
633e8c58f68d53e6cc9dbf59201c7bdfb8ad04a1cdSatoshi Kataoka
644a3db7057f77dc85311fb1f94934b5a004ab613eSatoshi Kataoka    bool hasTouchPositionCorrectionData() const {
654a3db7057f77dc85311fb1f94934b5a004ab613eSatoshi Kataoka        return HAS_TOUCH_POSITION_CORRECTION_DATA;
664a3db7057f77dc85311fb1f94934b5a004ab613eSatoshi Kataoka    }
674a3db7057f77dc85311fb1f94934b5a004ab613eSatoshi Kataoka
686b4a1d79eba19a55715e20b4ee75b3934f397db2Satoshi Kataoka    int getMostCommonKeyWidth() const {
696b4a1d79eba19a55715e20b4ee75b3934f397db2Satoshi Kataoka        return MOST_COMMON_KEY_WIDTH;
706b4a1d79eba19a55715e20b4ee75b3934f397db2Satoshi Kataoka    }
716b4a1d79eba19a55715e20b4ee75b3934f397db2Satoshi Kataoka
724a3db7057f77dc85311fb1f94934b5a004ab613eSatoshi Kataoka    int getMostCommonKeyWidthSquare() const {
734a3db7057f77dc85311fb1f94934b5a004ab613eSatoshi Kataoka        return MOST_COMMON_KEY_WIDTH_SQUARE;
744a3db7057f77dc85311fb1f94934b5a004ab613eSatoshi Kataoka    }
754a3db7057f77dc85311fb1f94934b5a004ab613eSatoshi Kataoka
769e0c711a6230af1db0753af401804c95e4bee69dKen Wakasa    const char *getLocaleStr() const {
779e0c711a6230af1db0753af401804c95e4bee69dKen Wakasa        return mLocaleStr;
784a3db7057f77dc85311fb1f94934b5a004ab613eSatoshi Kataoka    }
794a3db7057f77dc85311fb1f94934b5a004ab613eSatoshi Kataoka
804a3db7057f77dc85311fb1f94934b5a004ab613eSatoshi Kataoka    int getKeyCount() const {
814a3db7057f77dc85311fb1f94934b5a004ab613eSatoshi Kataoka        return KEY_COUNT;
824a3db7057f77dc85311fb1f94934b5a004ab613eSatoshi Kataoka    }
834a3db7057f77dc85311fb1f94934b5a004ab613eSatoshi Kataoka
844a3db7057f77dc85311fb1f94934b5a004ab613eSatoshi Kataoka    int getCellHeight() const {
854a3db7057f77dc85311fb1f94934b5a004ab613eSatoshi Kataoka        return CELL_HEIGHT;
864a3db7057f77dc85311fb1f94934b5a004ab613eSatoshi Kataoka    }
874a3db7057f77dc85311fb1f94934b5a004ab613eSatoshi Kataoka
884a3db7057f77dc85311fb1f94934b5a004ab613eSatoshi Kataoka    int getCellWidth() const {
894a3db7057f77dc85311fb1f94934b5a004ab613eSatoshi Kataoka        return CELL_WIDTH;
904a3db7057f77dc85311fb1f94934b5a004ab613eSatoshi Kataoka    }
914a3db7057f77dc85311fb1f94934b5a004ab613eSatoshi Kataoka
924a3db7057f77dc85311fb1f94934b5a004ab613eSatoshi Kataoka    int getGridWidth() const {
934a3db7057f77dc85311fb1f94934b5a004ab613eSatoshi Kataoka        return GRID_WIDTH;
944a3db7057f77dc85311fb1f94934b5a004ab613eSatoshi Kataoka    }
954a3db7057f77dc85311fb1f94934b5a004ab613eSatoshi Kataoka
964a3db7057f77dc85311fb1f94934b5a004ab613eSatoshi Kataoka    int getGridHeight() const {
974a3db7057f77dc85311fb1f94934b5a004ab613eSatoshi Kataoka        return GRID_HEIGHT;
984a3db7057f77dc85311fb1f94934b5a004ab613eSatoshi Kataoka    }
99635f68e8222901d607a5ca6fab95985bc496d72asatok
10095a49a527ac9c2c97cfcc758bd6f0d58fb4ad9c0Keisuke Kuroyanagi    int getKeyboardWidth() const {
10195a49a527ac9c2c97cfcc758bd6f0d58fb4ad9c0Keisuke Kuroyanagi        return KEYBOARD_WIDTH;
10295a49a527ac9c2c97cfcc758bd6f0d58fb4ad9c0Keisuke Kuroyanagi    }
10395a49a527ac9c2c97cfcc758bd6f0d58fb4ad9c0Keisuke Kuroyanagi
10495a49a527ac9c2c97cfcc758bd6f0d58fb4ad9c0Keisuke Kuroyanagi    int getKeyboardHeight() const {
10595a49a527ac9c2c97cfcc758bd6f0d58fb4ad9c0Keisuke Kuroyanagi        return KEYBOARD_HEIGHT;
10695a49a527ac9c2c97cfcc758bd6f0d58fb4ad9c0Keisuke Kuroyanagi    }
10795a49a527ac9c2c97cfcc758bd6f0d58fb4ad9c0Keisuke Kuroyanagi
1085964d4e607008d29cca3bc07c878fbc7eb540a1bKen Wakasa    int getKeyCenterXOfCodePointG(int charCode) const;
1095964d4e607008d29cca3bc07c878fbc7eb540a1bKen Wakasa    int getKeyCenterYOfCodePointG(int charCode) const;
1105964d4e607008d29cca3bc07c878fbc7eb540a1bKen Wakasa    int getKeyCenterXOfKeyIdG(int keyId) const;
1115964d4e607008d29cca3bc07c878fbc7eb540a1bKen Wakasa    int getKeyCenterYOfKeyIdG(int keyId) const;
1126b4a1d79eba19a55715e20b4ee75b3934f397db2Satoshi Kataoka    int getKeyKeyDistanceG(int key0, int key1) const;
1136b4a1d79eba19a55715e20b4ee75b3934f397db2Satoshi Kataoka
114e12e9b5b69e6242af61ee690a81bedde1bdd4936Ken Wakasa private:
1151bc038c5e40bd0fa7a44331a569abe3ae88f0152satok    DISALLOW_IMPLICIT_CONSTRUCTORS(ProximityInfo);
116162c211b44c1546b2e9be36e0cec50de497217a9Ken Wakasa    static const float NOT_A_DISTANCE_FLOAT;
1170e1f656c1be7f2916cf57c94d99b001795856270Yusuke Nojima
118817e517e463cb32726ff5a62196ac8744848e29bsatok    int getStartIndexFromCoordinates(const int x, const int y) const;
1196b4a1d79eba19a55715e20b4ee75b3934f397db2Satoshi Kataoka    void initializeG();
120a4c1f1c1fde5e9492523842dd95a4c9f17f40c3aYusuke Nojima    float calculateNormalizedSquaredDistance(const int keyIndex, const int inputIndex) const;
1211caff47ecdfcf413df709371a919cf9377e26bf7satok    bool hasInputCoordinates() const;
122fee0ac60b1cd0a4760ca8f310ff8a86b925d833bKen Wakasa    int squaredDistanceToEdge(const int keyId, const int x, const int y) const;
123fee0ac60b1cd0a4760ca8f310ff8a86b925d833bKen Wakasa    bool isOnKey(const int keyId, const int x, const int y) const {
124fee0ac60b1cd0a4760ca8f310ff8a86b925d833bKen Wakasa        if (keyId < 0) return true; // NOT_A_ID is -1, but return whenever < 0 just in case
125fee0ac60b1cd0a4760ca8f310ff8a86b925d833bKen Wakasa        const int left = mKeyXCoordinates[keyId];
126fee0ac60b1cd0a4760ca8f310ff8a86b925d833bKen Wakasa        const int top = mKeyYCoordinates[keyId];
127fee0ac60b1cd0a4760ca8f310ff8a86b925d833bKen Wakasa        const int right = left + mKeyWidths[keyId] + 1;
128fee0ac60b1cd0a4760ca8f310ff8a86b925d833bKen Wakasa        const int bottom = top + mKeyHeights[keyId];
129fee0ac60b1cd0a4760ca8f310ff8a86b925d833bKen Wakasa        return left < right && top < bottom && x >= left && x < right && y >= top && y < bottom;
130fee0ac60b1cd0a4760ca8f310ff8a86b925d833bKen Wakasa    }
131c25c7ccf25dd45464b82d29adca067f9a941c11cYusuke Nojima
132de3070a71b39742c3ac7b613f45af88cc95c1205Ken Wakasa    const int MAX_PROXIMITY_CHARS_SIZE;
1338fbd55229243cb66c03d5ea1f79dfb39f596590dsatok    const int GRID_WIDTH;
1348fbd55229243cb66c03d5ea1f79dfb39f596590dsatok    const int GRID_HEIGHT;
1356b4a1d79eba19a55715e20b4ee75b3934f397db2Satoshi Kataoka    const int MOST_COMMON_KEY_WIDTH;
136a70ee6e3b3fe65acab205b935ebd52e7bb0eccb8satok    const int MOST_COMMON_KEY_WIDTH_SQUARE;
137de3070a71b39742c3ac7b613f45af88cc95c1205Ken Wakasa    const int CELL_WIDTH;
138de3070a71b39742c3ac7b613f45af88cc95c1205Ken Wakasa    const int CELL_HEIGHT;
1390e1f656c1be7f2916cf57c94d99b001795856270Yusuke Nojima    const int KEY_COUNT;
14095a49a527ac9c2c97cfcc758bd6f0d58fb4ad9c0Keisuke Kuroyanagi    const int KEYBOARD_WIDTH;
14195a49a527ac9c2c97cfcc758bd6f0d58fb4ad9c0Keisuke Kuroyanagi    const int KEYBOARD_HEIGHT;
142a4c1f1c1fde5e9492523842dd95a4c9f17f40c3aYusuke Nojima    const bool HAS_TOUCH_POSITION_CORRECTION_DATA;
1439e0c711a6230af1db0753af401804c95e4bee69dKen Wakasa    char mLocaleStr[MAX_LOCALE_STRING_LENGTH];
1440cb2097a45a41875ec2265da316eb770565b6706satok    int32_t *mProximityCharsArray;
1450e1f656c1be7f2916cf57c94d99b001795856270Yusuke Nojima    int32_t mKeyXCoordinates[MAX_KEY_COUNT_IN_A_KEYBOARD];
1460e1f656c1be7f2916cf57c94d99b001795856270Yusuke Nojima    int32_t mKeyYCoordinates[MAX_KEY_COUNT_IN_A_KEYBOARD];
1470e1f656c1be7f2916cf57c94d99b001795856270Yusuke Nojima    int32_t mKeyWidths[MAX_KEY_COUNT_IN_A_KEYBOARD];
1480e1f656c1be7f2916cf57c94d99b001795856270Yusuke Nojima    int32_t mKeyHeights[MAX_KEY_COUNT_IN_A_KEYBOARD];
149f2789819bd005b5b0581e8439601b5501306327dKen Wakasa    int32_t mKeyCodePoints[MAX_KEY_COUNT_IN_A_KEYBOARD];
150ad35835baccb4101c3d8766fadbf4d127e41b6cbYusuke Nojima    float mSweetSpotCenterXs[MAX_KEY_COUNT_IN_A_KEYBOARD];
151ad35835baccb4101c3d8766fadbf4d127e41b6cbYusuke Nojima    float mSweetSpotCenterYs[MAX_KEY_COUNT_IN_A_KEYBOARD];
152ad35835baccb4101c3d8766fadbf4d127e41b6cbYusuke Nojima    float mSweetSpotRadii[MAX_KEY_COUNT_IN_A_KEYBOARD];
153132168519e1d681ea1b8fd7fcf283155a0b3997eTom Ouyang    hash_map_compat<int, int> mCodeToKeyMap;
1546b4a1d79eba19a55715e20b4ee75b3934f397db2Satoshi Kataoka
155f2789819bd005b5b0581e8439601b5501306327dKen Wakasa    int mKeyIndexToCodePointG[MAX_KEY_COUNT_IN_A_KEYBOARD];
1566b4a1d79eba19a55715e20b4ee75b3934f397db2Satoshi Kataoka    int mCenterXsG[MAX_KEY_COUNT_IN_A_KEYBOARD];
1576b4a1d79eba19a55715e20b4ee75b3934f397db2Satoshi Kataoka    int mCenterYsG[MAX_KEY_COUNT_IN_A_KEYBOARD];
1586b4a1d79eba19a55715e20b4ee75b3934f397db2Satoshi Kataoka    int mKeyKeyDistancesG[MAX_KEY_COUNT_IN_A_KEYBOARD][MAX_KEY_COUNT_IN_A_KEYBOARD];
1593e8c58f68d53e6cc9dbf59201c7bdfb8ad04a1cdSatoshi Kataoka    // TODO: move to correction.h
1608fbd55229243cb66c03d5ea1f79dfb39f596590dsatok};
161ce9e52a12a6af8fca0eba42aaae24602fbd5c998Ken Wakasa} // namespace latinime
1628fbd55229243cb66c03d5ea1f79dfb39f596590dsatok#endif // LATINIME_PROXIMITY_INFO_H
163