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