proximity_info.cpp revision f1008c550168e50f930ea1e043000b395ce0f129
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
17f1008c550168e50f930ea1e043000b395ce0f129Ken Wakasa#include <cassert>
18f1008c550168e50f930ea1e043000b395ce0f129Ken Wakasa#include <cmath>
19f1008c550168e50f930ea1e043000b395ce0f129Ken Wakasa#include <cstring>
20552c3c27f04e6769e40cffbce3a9e8eed1269294satok#include <string>
218fbd55229243cb66c03d5ea1f79dfb39f596590dsatok
22817e517e463cb32726ff5a62196ac8744848e29bsatok#define LOG_TAG "LatinIME: proximity_info.cpp"
23817e517e463cb32726ff5a62196ac8744848e29bsatok
24552c3c27f04e6769e40cffbce3a9e8eed1269294satok#include "additional_proximity_chars.h"
253b088a2f365a9ce06f58243c83cb961ea2920b7eKen Wakasa#include "defines.h"
26d24df43eaf1f7a7a9a9fcf31a45f0c2b2e11b698satok#include "dictionary.h"
278fbd55229243cb66c03d5ea1f79dfb39f596590dsatok#include "proximity_info.h"
283e8c58f68d53e6cc9dbf59201c7bdfb8ad04a1cdSatoshi Kataoka#include "proximity_info_state.h"
298fbd55229243cb66c03d5ea1f79dfb39f596590dsatok
308fbd55229243cb66c03d5ea1f79dfb39f596590dsatoknamespace latinime {
31ce9e52a12a6af8fca0eba42aaae24602fbd5c998Ken Wakasa
32de2f8424ea7e201ab8ee0d3c64fac0b52514d24eYusuke Nojimainline void copyOrFillZero(void *to, const void *from, size_t size) {
33de2f8424ea7e201ab8ee0d3c64fac0b52514d24eYusuke Nojima    if (from) {
34de2f8424ea7e201ab8ee0d3c64fac0b52514d24eYusuke Nojima        memcpy(to, from, size);
35de2f8424ea7e201ab8ee0d3c64fac0b52514d24eYusuke Nojima    } else {
36de2f8424ea7e201ab8ee0d3c64fac0b52514d24eYusuke Nojima        memset(to, 0, size);
37de2f8424ea7e201ab8ee0d3c64fac0b52514d24eYusuke Nojima    }
38de2f8424ea7e201ab8ee0d3c64fac0b52514d24eYusuke Nojima}
39de2f8424ea7e201ab8ee0d3c64fac0b52514d24eYusuke Nojima
40552c3c27f04e6769e40cffbce3a9e8eed1269294satokProximityInfo::ProximityInfo(const std::string localeStr, const int maxProximityCharsSize,
41552c3c27f04e6769e40cffbce3a9e8eed1269294satok        const int keyboardWidth, const int keyboardHeight, const int gridWidth,
42552c3c27f04e6769e40cffbce3a9e8eed1269294satok        const int gridHeight, const int mostCommonKeyWidth,
430cb2097a45a41875ec2265da316eb770565b6706satok        const int32_t *proximityCharsArray, const int keyCount, const int32_t *keyXCoordinates,
440e1f656c1be7f2916cf57c94d99b001795856270Yusuke Nojima        const int32_t *keyYCoordinates, const int32_t *keyWidths, const int32_t *keyHeights,
45ad35835baccb4101c3d8766fadbf4d127e41b6cbYusuke Nojima        const int32_t *keyCharCodes, const float *sweetSpotCenterXs, const float *sweetSpotCenterYs,
46ad35835baccb4101c3d8766fadbf4d127e41b6cbYusuke Nojima        const float *sweetSpotRadii)
47817e517e463cb32726ff5a62196ac8744848e29bsatok        : MAX_PROXIMITY_CHARS_SIZE(maxProximityCharsSize), KEYBOARD_WIDTH(keyboardWidth),
48817e517e463cb32726ff5a62196ac8744848e29bsatok          KEYBOARD_HEIGHT(keyboardHeight), GRID_WIDTH(gridWidth), GRID_HEIGHT(gridHeight),
49a70ee6e3b3fe65acab205b935ebd52e7bb0eccb8satok          MOST_COMMON_KEY_WIDTH_SQUARE(mostCommonKeyWidth * mostCommonKeyWidth),
50817e517e463cb32726ff5a62196ac8744848e29bsatok          CELL_WIDTH((keyboardWidth + gridWidth - 1) / gridWidth),
510e1f656c1be7f2916cf57c94d99b001795856270Yusuke Nojima          CELL_HEIGHT((keyboardHeight + gridHeight - 1) / gridHeight),
52258bfe66e0fcfc89b59534a9cc7f50ff07d5f78dYusuke Nojima          KEY_COUNT(min(keyCount, MAX_KEY_COUNT_IN_A_KEYBOARD)),
53a4c1f1c1fde5e9492523842dd95a4c9f17f40c3aYusuke Nojima          HAS_TOUCH_POSITION_CORRECTION_DATA(keyCount > 0 && keyXCoordinates && keyYCoordinates
54a4c1f1c1fde5e9492523842dd95a4c9f17f40c3aYusuke Nojima                  && keyWidths && keyHeights && keyCharCodes && sweetSpotCenterXs
55a4c1f1c1fde5e9492523842dd95a4c9f17f40c3aYusuke Nojima                  && sweetSpotCenterYs && sweetSpotRadii),
563e8c58f68d53e6cc9dbf59201c7bdfb8ad04a1cdSatoshi Kataoka          mLocaleStr(localeStr) {
571035bc990d9d704d8cf1002548e5dddb3ba96797satok    const int proximityGridLength = GRID_WIDTH * GRID_HEIGHT * MAX_PROXIMITY_CHARS_SIZE;
58817e517e463cb32726ff5a62196ac8744848e29bsatok    if (DEBUG_PROXIMITY_INFO) {
599fb6f47a6a11f62d134d4d6259181ac987fc1ad3satok        AKLOGI("Create proximity info array %d", proximityGridLength);
60817e517e463cb32726ff5a62196ac8744848e29bsatok    }
613e8c58f68d53e6cc9dbf59201c7bdfb8ad04a1cdSatoshi Kataoka    mProximityCharsArray = new int32_t[proximityGridLength];
628c8ca59dd547cce979f1b54f2ff8853a2978a162Jean Chalard    memcpy(mProximityCharsArray, proximityCharsArray,
638c8ca59dd547cce979f1b54f2ff8853a2978a162Jean Chalard            proximityGridLength * sizeof(mProximityCharsArray[0]));
640e1f656c1be7f2916cf57c94d99b001795856270Yusuke Nojima
65de2f8424ea7e201ab8ee0d3c64fac0b52514d24eYusuke Nojima    copyOrFillZero(mKeyXCoordinates, keyXCoordinates, KEY_COUNT * sizeof(mKeyXCoordinates[0]));
66de2f8424ea7e201ab8ee0d3c64fac0b52514d24eYusuke Nojima    copyOrFillZero(mKeyYCoordinates, keyYCoordinates, KEY_COUNT * sizeof(mKeyYCoordinates[0]));
67de2f8424ea7e201ab8ee0d3c64fac0b52514d24eYusuke Nojima    copyOrFillZero(mKeyWidths, keyWidths, KEY_COUNT * sizeof(mKeyWidths[0]));
68de2f8424ea7e201ab8ee0d3c64fac0b52514d24eYusuke Nojima    copyOrFillZero(mKeyHeights, keyHeights, KEY_COUNT * sizeof(mKeyHeights[0]));
69de2f8424ea7e201ab8ee0d3c64fac0b52514d24eYusuke Nojima    copyOrFillZero(mKeyCharCodes, keyCharCodes, KEY_COUNT * sizeof(mKeyCharCodes[0]));
70ad35835baccb4101c3d8766fadbf4d127e41b6cbYusuke Nojima    copyOrFillZero(mSweetSpotCenterXs, sweetSpotCenterXs,
71ad35835baccb4101c3d8766fadbf4d127e41b6cbYusuke Nojima            KEY_COUNT * sizeof(mSweetSpotCenterXs[0]));
72ad35835baccb4101c3d8766fadbf4d127e41b6cbYusuke Nojima    copyOrFillZero(mSweetSpotCenterYs, sweetSpotCenterYs,
73ad35835baccb4101c3d8766fadbf4d127e41b6cbYusuke Nojima            KEY_COUNT * sizeof(mSweetSpotCenterYs[0]));
74ad35835baccb4101c3d8766fadbf4d127e41b6cbYusuke Nojima    copyOrFillZero(mSweetSpotRadii, sweetSpotRadii, KEY_COUNT * sizeof(mSweetSpotRadii[0]));
750e1f656c1be7f2916cf57c94d99b001795856270Yusuke Nojima
760e1f656c1be7f2916cf57c94d99b001795856270Yusuke Nojima    initializeCodeToKeyIndex();
770e1f656c1be7f2916cf57c94d99b001795856270Yusuke Nojima}
780e1f656c1be7f2916cf57c94d99b001795856270Yusuke Nojima
790e1f656c1be7f2916cf57c94d99b001795856270Yusuke Nojima// Build the reversed look up table from the char code to the index in mKeyXCoordinates,
800e1f656c1be7f2916cf57c94d99b001795856270Yusuke Nojima// mKeyYCoordinates, mKeyWidths, mKeyHeights, mKeyCharCodes.
810e1f656c1be7f2916cf57c94d99b001795856270Yusuke Nojimavoid ProximityInfo::initializeCodeToKeyIndex() {
82ad35835baccb4101c3d8766fadbf4d127e41b6cbYusuke Nojima    memset(mCodeToKeyIndex, -1, (MAX_CHAR_CODE + 1) * sizeof(mCodeToKeyIndex[0]));
830e1f656c1be7f2916cf57c94d99b001795856270Yusuke Nojima    for (int i = 0; i < KEY_COUNT; ++i) {
840e1f656c1be7f2916cf57c94d99b001795856270Yusuke Nojima        const int code = mKeyCharCodes[i];
85ad35835baccb4101c3d8766fadbf4d127e41b6cbYusuke Nojima        if (0 <= code && code <= MAX_CHAR_CODE) {
860e1f656c1be7f2916cf57c94d99b001795856270Yusuke Nojima            mCodeToKeyIndex[code] = i;
87ad35835baccb4101c3d8766fadbf4d127e41b6cbYusuke Nojima        }
880e1f656c1be7f2916cf57c94d99b001795856270Yusuke Nojima    }
898fbd55229243cb66c03d5ea1f79dfb39f596590dsatok}
908fbd55229243cb66c03d5ea1f79dfb39f596590dsatok
918fbd55229243cb66c03d5ea1f79dfb39f596590dsatokProximityInfo::~ProximityInfo() {
928fbd55229243cb66c03d5ea1f79dfb39f596590dsatok    delete[] mProximityCharsArray;
938fbd55229243cb66c03d5ea1f79dfb39f596590dsatok}
94817e517e463cb32726ff5a62196ac8744848e29bsatok
95817e517e463cb32726ff5a62196ac8744848e29bsatokinline int ProximityInfo::getStartIndexFromCoordinates(const int x, const int y) const {
963c4bb7747d1a16d6b9d2d34992bad250069632a7satok    return ((y / CELL_HEIGHT) * GRID_WIDTH + (x / CELL_WIDTH))
97817e517e463cb32726ff5a62196ac8744848e29bsatok            * MAX_PROXIMITY_CHARS_SIZE;
98817e517e463cb32726ff5a62196ac8744848e29bsatok}
99817e517e463cb32726ff5a62196ac8744848e29bsatok
100817e517e463cb32726ff5a62196ac8744848e29bsatokbool ProximityInfo::hasSpaceProximity(const int x, const int y) const {
101744dab691e45ff8c5ca9745ee673f50060bcb7a9satok    if (x < 0 || y < 0) {
102744dab691e45ff8c5ca9745ee673f50060bcb7a9satok        if (DEBUG_DICT) {
1039fb6f47a6a11f62d134d4d6259181ac987fc1ad3satok            AKLOGI("HasSpaceProximity: Illegal coordinates (%d, %d)", x, y);
1041a6da631ab7c6ed895964978be8f455b41e019bbsatok            assert(false);
105744dab691e45ff8c5ca9745ee673f50060bcb7a9satok        }
106744dab691e45ff8c5ca9745ee673f50060bcb7a9satok        return false;
107744dab691e45ff8c5ca9745ee673f50060bcb7a9satok    }
108744dab691e45ff8c5ca9745ee673f50060bcb7a9satok
109817e517e463cb32726ff5a62196ac8744848e29bsatok    const int startIndex = getStartIndexFromCoordinates(x, y);
110817e517e463cb32726ff5a62196ac8744848e29bsatok    if (DEBUG_PROXIMITY_INFO) {
1119fb6f47a6a11f62d134d4d6259181ac987fc1ad3satok        AKLOGI("hasSpaceProximity: index %d, %d, %d", startIndex, x, y);
112817e517e463cb32726ff5a62196ac8744848e29bsatok    }
1130bbb917d12358e0264796e75dea888f244761b64Ken Wakasa    int32_t *proximityCharsArray = mProximityCharsArray;
114817e517e463cb32726ff5a62196ac8744848e29bsatok    for (int i = 0; i < MAX_PROXIMITY_CHARS_SIZE; ++i) {
115817e517e463cb32726ff5a62196ac8744848e29bsatok        if (DEBUG_PROXIMITY_INFO) {
1169fb6f47a6a11f62d134d4d6259181ac987fc1ad3satok            AKLOGI("Index: %d", mProximityCharsArray[startIndex + i]);
117817e517e463cb32726ff5a62196ac8744848e29bsatok        }
1183e8c58f68d53e6cc9dbf59201c7bdfb8ad04a1cdSatoshi Kataoka        if (proximityCharsArray[startIndex + i] == KEYCODE_SPACE) {
119817e517e463cb32726ff5a62196ac8744848e29bsatok            return true;
120817e517e463cb32726ff5a62196ac8744848e29bsatok        }
121817e517e463cb32726ff5a62196ac8744848e29bsatok    }
122817e517e463cb32726ff5a62196ac8744848e29bsatok    return false;
1238fbd55229243cb66c03d5ea1f79dfb39f596590dsatok}
124ce9e52a12a6af8fca0eba42aaae24602fbd5c998Ken Wakasa
1259df4a4527a9bc2e671f644d6e2ec0121385740ecsatokint ProximityInfo::squaredDistanceToEdge(const int keyId, const int x, const int y) const {
126081616cd2f472295449268cecb570771b969cba3Jean Chalard    if (keyId < 0) return true; // NOT_A_ID is -1, but return whenever < 0 just in case
127a70ee6e3b3fe65acab205b935ebd52e7bb0eccb8satok    const int left = mKeyXCoordinates[keyId];
128a70ee6e3b3fe65acab205b935ebd52e7bb0eccb8satok    const int top = mKeyYCoordinates[keyId];
1291caff47ecdfcf413df709371a919cf9377e26bf7satok    const int right = left + mKeyWidths[keyId];
130a70ee6e3b3fe65acab205b935ebd52e7bb0eccb8satok    const int bottom = top + mKeyHeights[keyId];
131a70ee6e3b3fe65acab205b935ebd52e7bb0eccb8satok    const int edgeX = x < left ? left : (x > right ? right : x);
132a70ee6e3b3fe65acab205b935ebd52e7bb0eccb8satok    const int edgeY = y < top ? top : (y > bottom ? bottom : y);
133a70ee6e3b3fe65acab205b935ebd52e7bb0eccb8satok    const int dx = x - edgeX;
134a70ee6e3b3fe65acab205b935ebd52e7bb0eccb8satok    const int dy = y - edgeY;
135a70ee6e3b3fe65acab205b935ebd52e7bb0eccb8satok    return dx * dx + dy * dy;
136a70ee6e3b3fe65acab205b935ebd52e7bb0eccb8satok}
137a70ee6e3b3fe65acab205b935ebd52e7bb0eccb8satok
138a70ee6e3b3fe65acab205b935ebd52e7bb0eccb8satokvoid ProximityInfo::calculateNearbyKeyCodes(
1399df4a4527a9bc2e671f644d6e2ec0121385740ecsatok        const int x, const int y, const int32_t primaryKey, int *inputCodes) const {
1403e8c58f68d53e6cc9dbf59201c7bdfb8ad04a1cdSatoshi Kataoka    int32_t *proximityCharsArray = mProximityCharsArray;
141a70ee6e3b3fe65acab205b935ebd52e7bb0eccb8satok    int insertPos = 0;
142a70ee6e3b3fe65acab205b935ebd52e7bb0eccb8satok    inputCodes[insertPos++] = primaryKey;
143a70ee6e3b3fe65acab205b935ebd52e7bb0eccb8satok    const int startIndex = getStartIndexFromCoordinates(x, y);
14452612a0d1b0ce7796fa0a0b50bfda172ebc2a5efJean Chalard    if (startIndex >= 0) {
14588ec125cfcbb06e84f611dd26097efa9731979b7Jean Chalard        for (int i = 0; i < MAX_PROXIMITY_CHARS_SIZE; ++i) {
1463e8c58f68d53e6cc9dbf59201c7bdfb8ad04a1cdSatoshi Kataoka            const int32_t c = proximityCharsArray[startIndex + i];
14788ec125cfcbb06e84f611dd26097efa9731979b7Jean Chalard            if (c < KEYCODE_SPACE || c == primaryKey) {
14888ec125cfcbb06e84f611dd26097efa9731979b7Jean Chalard                continue;
14988ec125cfcbb06e84f611dd26097efa9731979b7Jean Chalard            }
15088ec125cfcbb06e84f611dd26097efa9731979b7Jean Chalard            const int keyIndex = getKeyIndex(c);
15188ec125cfcbb06e84f611dd26097efa9731979b7Jean Chalard            const bool onKey = isOnKey(keyIndex, x, y);
15288ec125cfcbb06e84f611dd26097efa9731979b7Jean Chalard            const int distance = squaredDistanceToEdge(keyIndex, x, y);
15388ec125cfcbb06e84f611dd26097efa9731979b7Jean Chalard            if (onKey || distance < MOST_COMMON_KEY_WIDTH_SQUARE) {
15488ec125cfcbb06e84f611dd26097efa9731979b7Jean Chalard                inputCodes[insertPos++] = c;
15588ec125cfcbb06e84f611dd26097efa9731979b7Jean Chalard                if (insertPos >= MAX_PROXIMITY_CHARS_SIZE) {
15688ec125cfcbb06e84f611dd26097efa9731979b7Jean Chalard                    if (DEBUG_DICT) {
15788ec125cfcbb06e84f611dd26097efa9731979b7Jean Chalard                        assert(false);
15888ec125cfcbb06e84f611dd26097efa9731979b7Jean Chalard                    }
15988ec125cfcbb06e84f611dd26097efa9731979b7Jean Chalard                    return;
1600cb2097a45a41875ec2265da316eb770565b6706satok                }
161a70ee6e3b3fe65acab205b935ebd52e7bb0eccb8satok            }
162a70ee6e3b3fe65acab205b935ebd52e7bb0eccb8satok        }
16388ec125cfcbb06e84f611dd26097efa9731979b7Jean Chalard        const int additionalProximitySize =
16488ec125cfcbb06e84f611dd26097efa9731979b7Jean Chalard                AdditionalProximityChars::getAdditionalCharsSize(&mLocaleStr, primaryKey);
16588ec125cfcbb06e84f611dd26097efa9731979b7Jean Chalard        if (additionalProximitySize > 0) {
16688ec125cfcbb06e84f611dd26097efa9731979b7Jean Chalard            inputCodes[insertPos++] = ADDITIONAL_PROXIMITY_CHAR_DELIMITER_CODE;
16788ec125cfcbb06e84f611dd26097efa9731979b7Jean Chalard            if (insertPos >= MAX_PROXIMITY_CHARS_SIZE) {
1683094d12cdcf0583b44f1b32468f0189b530d8c73Jean Chalard                if (DEBUG_DICT) {
1693094d12cdcf0583b44f1b32468f0189b530d8c73Jean Chalard                    assert(false);
1703094d12cdcf0583b44f1b32468f0189b530d8c73Jean Chalard                }
1713094d12cdcf0583b44f1b32468f0189b530d8c73Jean Chalard                return;
1721caff47ecdfcf413df709371a919cf9377e26bf7satok            }
1731caff47ecdfcf413df709371a919cf9377e26bf7satok
1740bbb917d12358e0264796e75dea888f244761b64Ken Wakasa            const int32_t *additionalProximityChars =
17588ec125cfcbb06e84f611dd26097efa9731979b7Jean Chalard                    AdditionalProximityChars::getAdditionalChars(&mLocaleStr, primaryKey);
17688ec125cfcbb06e84f611dd26097efa9731979b7Jean Chalard            for (int j = 0; j < additionalProximitySize; ++j) {
17788ec125cfcbb06e84f611dd26097efa9731979b7Jean Chalard                const int32_t ac = additionalProximityChars[j];
17888ec125cfcbb06e84f611dd26097efa9731979b7Jean Chalard                int k = 0;
17988ec125cfcbb06e84f611dd26097efa9731979b7Jean Chalard                for (; k < insertPos; ++k) {
18088ec125cfcbb06e84f611dd26097efa9731979b7Jean Chalard                    if ((int)ac == inputCodes[k]) {
18188ec125cfcbb06e84f611dd26097efa9731979b7Jean Chalard                        break;
18288ec125cfcbb06e84f611dd26097efa9731979b7Jean Chalard                    }
1835eec574cf0eb6b8ec23723b5f566563453edd42fsatok                }
18488ec125cfcbb06e84f611dd26097efa9731979b7Jean Chalard                if (k < insertPos) {
18588ec125cfcbb06e84f611dd26097efa9731979b7Jean Chalard                    continue;
1860cb2097a45a41875ec2265da316eb770565b6706satok                }
18788ec125cfcbb06e84f611dd26097efa9731979b7Jean Chalard                inputCodes[insertPos++] = ac;
18888ec125cfcbb06e84f611dd26097efa9731979b7Jean Chalard                if (insertPos >= MAX_PROXIMITY_CHARS_SIZE) {
18988ec125cfcbb06e84f611dd26097efa9731979b7Jean Chalard                    if (DEBUG_DICT) {
19088ec125cfcbb06e84f611dd26097efa9731979b7Jean Chalard                        assert(false);
19188ec125cfcbb06e84f611dd26097efa9731979b7Jean Chalard                    }
19288ec125cfcbb06e84f611dd26097efa9731979b7Jean Chalard                    return;
1933094d12cdcf0583b44f1b32468f0189b530d8c73Jean Chalard                }
1940cb2097a45a41875ec2265da316eb770565b6706satok            }
1955eec574cf0eb6b8ec23723b5f566563453edd42fsatok        }
19652612a0d1b0ce7796fa0a0b50bfda172ebc2a5efJean Chalard    }
1970cb2097a45a41875ec2265da316eb770565b6706satok    // Add a delimiter for the proximity characters
1981caff47ecdfcf413df709371a919cf9377e26bf7satok    for (int i = insertPos; i < MAX_PROXIMITY_CHARS_SIZE; ++i) {
1991caff47ecdfcf413df709371a919cf9377e26bf7satok        inputCodes[i] = NOT_A_CODE;
2001caff47ecdfcf413df709371a919cf9377e26bf7satok    }
201a70ee6e3b3fe65acab205b935ebd52e7bb0eccb8satok}
202a70ee6e3b3fe65acab205b935ebd52e7bb0eccb8satok
203a4c1f1c1fde5e9492523842dd95a4c9f17f40c3aYusuke Nojimaint ProximityInfo::getKeyIndex(const int c) const {
2041caff47ecdfcf413df709371a919cf9377e26bf7satok    if (KEY_COUNT == 0) {
205a4c1f1c1fde5e9492523842dd95a4c9f17f40c3aYusuke Nojima        // We do not have the coordinate data
206bbc25607f01cf9a0cdbc3e8664b27c7f26bd6e18Jean Chalard        return NOT_AN_INDEX;
20716717159fffc7731669143a8e9ed866e7d88ecefYusuke Nojima    }
2086e3cb27cffa525d555b289111678f6fa0495447eTadashi G. Takaoka    const unsigned short baseLowerC = toBaseLowerCase(c);
209a4c1f1c1fde5e9492523842dd95a4c9f17f40c3aYusuke Nojima    if (baseLowerC > MAX_CHAR_CODE) {
210bbc25607f01cf9a0cdbc3e8664b27c7f26bd6e18Jean Chalard        return NOT_AN_INDEX;
21116717159fffc7731669143a8e9ed866e7d88ecefYusuke Nojima    }
212a4c1f1c1fde5e9492523842dd95a4c9f17f40c3aYusuke Nojima    return mCodeToKeyIndex[baseLowerC];
21316717159fffc7731669143a8e9ed866e7d88ecefYusuke Nojima}
214efb63246c2e5df29d62416d48f62e2b57b14de7cSatoshi Kataoka
215efb63246c2e5df29d62416d48f62e2b57b14de7cSatoshi Kataoka// TODO: [Staging] Optimize
216efb63246c2e5df29d62416d48f62e2b57b14de7cSatoshi Kataokavoid ProximityInfo::getCenters(int *centerXs, int *centerYs, int *codeToKeyIndex,
217efb63246c2e5df29d62416d48f62e2b57b14de7cSatoshi Kataoka        int *keyToCodeIndex, int *keyCount, int *keyWidth) const {
218efb63246c2e5df29d62416d48f62e2b57b14de7cSatoshi Kataoka    *keyCount = KEY_COUNT;
219efb63246c2e5df29d62416d48f62e2b57b14de7cSatoshi Kataoka    *keyWidth = sqrt((float)MOST_COMMON_KEY_WIDTH_SQUARE);
220efb63246c2e5df29d62416d48f62e2b57b14de7cSatoshi Kataoka
221efb63246c2e5df29d62416d48f62e2b57b14de7cSatoshi Kataoka    for (int i = 0; i < KEY_COUNT; ++i) {
222efb63246c2e5df29d62416d48f62e2b57b14de7cSatoshi Kataoka        const int code = mKeyCharCodes[i];
223efb63246c2e5df29d62416d48f62e2b57b14de7cSatoshi Kataoka        const int lowerCode = toBaseLowerCase(code);
224efb63246c2e5df29d62416d48f62e2b57b14de7cSatoshi Kataoka        centerXs[i] = mKeyXCoordinates[i] + mKeyWidths[i] / 2;
225efb63246c2e5df29d62416d48f62e2b57b14de7cSatoshi Kataoka        centerYs[i] = mKeyYCoordinates[i] + mKeyHeights[i] / 2;
226efb63246c2e5df29d62416d48f62e2b57b14de7cSatoshi Kataoka        codeToKeyIndex[code] = i;
227efb63246c2e5df29d62416d48f62e2b57b14de7cSatoshi Kataoka        if (code != lowerCode && lowerCode >= 0 && lowerCode <= MAX_CHAR_CODE) {
228efb63246c2e5df29d62416d48f62e2b57b14de7cSatoshi Kataoka            codeToKeyIndex[lowerCode] = i;
229efb63246c2e5df29d62416d48f62e2b57b14de7cSatoshi Kataoka            keyToCodeIndex[i] = lowerCode;
230efb63246c2e5df29d62416d48f62e2b57b14de7cSatoshi Kataoka        } else {
231efb63246c2e5df29d62416d48f62e2b57b14de7cSatoshi Kataoka            keyToCodeIndex[i] = code;
232efb63246c2e5df29d62416d48f62e2b57b14de7cSatoshi Kataoka        }
233efb63246c2e5df29d62416d48f62e2b57b14de7cSatoshi Kataoka    }
234efb63246c2e5df29d62416d48f62e2b57b14de7cSatoshi Kataoka}
235ce9e52a12a6af8fca0eba42aaae24602fbd5c998Ken Wakasa} // namespace latinime
236