aboutsummaryrefslogtreecommitdiffstats
path: root/native
diff options
context:
space:
mode:
Diffstat (limited to 'native')
-rw-r--r--native/jni/com_android_inputmethod_keyboard_ProximityInfo.cpp7
-rw-r--r--native/src/proximity_info.cpp43
-rw-r--r--native/src/proximity_info.h8
-rw-r--r--native/src/unigram_dictionary.cpp24
-rw-r--r--native/src/unigram_dictionary.h1
5 files changed, 73 insertions, 10 deletions
diff --git a/native/jni/com_android_inputmethod_keyboard_ProximityInfo.cpp b/native/jni/com_android_inputmethod_keyboard_ProximityInfo.cpp
index 6e4fefd72..844b23054 100644
--- a/native/jni/com_android_inputmethod_keyboard_ProximityInfo.cpp
+++ b/native/jni/com_android_inputmethod_keyboard_ProximityInfo.cpp
@@ -30,7 +30,7 @@ namespace latinime {
static jlong latinime_Keyboard_setProximityInfo(JNIEnv *env, jobject object,
jint maxProximityCharsSize, jint displayWidth, jint displayHeight, jint gridWidth,
- jint gridHeight, jintArray proximityCharsArray, jint keyCount,
+ jint gridHeight, jint mostCommonkeyWidth, jintArray proximityCharsArray, jint keyCount,
jintArray keyXCoordinateArray, jintArray keyYCoordinateArray, jintArray keyWidthArray,
jintArray keyHeightArray, jintArray keyCharCodeArray,
jfloatArray sweetSpotCenterXArray, jfloatArray sweetSpotCenterYArray,
@@ -45,7 +45,8 @@ static jlong latinime_Keyboard_setProximityInfo(JNIEnv *env, jobject object,
jfloat *sweetSpotCenterYs = safeGetFloatArrayElements(env, sweetSpotCenterYArray);
jfloat *sweetSpotRadii = safeGetFloatArrayElements(env, sweetSpotRadiusArray);
ProximityInfo *proximityInfo = new ProximityInfo(maxProximityCharsSize, displayWidth,
- displayHeight, gridWidth, gridHeight, (const uint32_t*)proximityChars,
+ displayHeight, gridWidth, gridHeight, mostCommonkeyWidth,
+ (const uint32_t*)proximityChars,
keyCount, (const int32_t*)keyXCoordinates, (const int32_t*)keyYCoordinates,
(const int32_t*)keyWidths, (const int32_t*)keyHeights, (const int32_t*)keyCharCodes,
(const float*)sweetSpotCenterXs, (const float*)sweetSpotCenterYs,
@@ -69,7 +70,7 @@ static void latinime_Keyboard_release(JNIEnv *env, jobject object, jlong proximi
}
static JNINativeMethod sKeyboardMethods[] = {
- {"setProximityInfoNative", "(IIIII[II[I[I[I[I[I[F[F[F)J",
+ {"setProximityInfoNative", "(IIIIII[II[I[I[I[I[I[F[F[F)J",
(void*)latinime_Keyboard_setProximityInfo},
{"releaseProximityInfoNative", "(J)V", (void*)latinime_Keyboard_release}
};
diff --git a/native/src/proximity_info.cpp b/native/src/proximity_info.cpp
index b6bab2274..ad19f58b5 100644
--- a/native/src/proximity_info.cpp
+++ b/native/src/proximity_info.cpp
@@ -35,12 +35,14 @@ inline void copyOrFillZero(void *to, const void *from, size_t size) {
ProximityInfo::ProximityInfo(const int maxProximityCharsSize, const int keyboardWidth,
const int keyboardHeight, const int gridWidth, const int gridHeight,
+ const int mostCommonKeyWidth,
const uint32_t *proximityCharsArray, const int keyCount, const int32_t *keyXCoordinates,
const int32_t *keyYCoordinates, const int32_t *keyWidths, const int32_t *keyHeights,
const int32_t *keyCharCodes, const float *sweetSpotCenterXs, const float *sweetSpotCenterYs,
const float *sweetSpotRadii)
: MAX_PROXIMITY_CHARS_SIZE(maxProximityCharsSize), KEYBOARD_WIDTH(keyboardWidth),
KEYBOARD_HEIGHT(keyboardHeight), GRID_WIDTH(gridWidth), GRID_HEIGHT(gridHeight),
+ MOST_COMMON_KEY_WIDTH_SQUARE(mostCommonKeyWidth * mostCommonKeyWidth),
CELL_WIDTH((keyboardWidth + gridWidth - 1) / gridWidth),
CELL_HEIGHT((keyboardHeight + gridHeight - 1) / gridHeight),
KEY_COUNT(min(keyCount, MAX_KEY_COUNT_IN_A_KEYBOARD)),
@@ -123,6 +125,47 @@ bool ProximityInfo::hasSpaceProximity(const int x, const int y) const {
return false;
}
+bool ProximityInfo::isOnKey(const int keyId, const int x, const int y) {
+ const int left = mKeyXCoordinates[keyId];
+ const int top = mKeyYCoordinates[keyId];
+ const int right = left + mKeyWidths[keyId] + 1;
+ const int bottom = top + mKeyHeights[keyId];
+ return left < right && top < bottom && x >= left && x < right && y >= top && y < bottom;
+}
+
+int ProximityInfo::squaredDistanceToEdge(const int keyId, const int x, const int y) {
+ const int left = mKeyXCoordinates[keyId];
+ const int top = mKeyYCoordinates[keyId];
+ const int right = left + mKeyWidths[keyId] + 1;
+ const int bottom = top + mKeyHeights[keyId];
+ const int edgeX = x < left ? left : (x > right ? right : x);
+ const int edgeY = y < top ? top : (y > bottom ? bottom : y);
+ const int dx = x - edgeX;
+ const int dy = y - edgeY;
+ return dx * dx + dy * dy;
+}
+
+void ProximityInfo::calculateNearbyKeyCodes(
+ const int x, const int y, const uint32_t primaryKey, int *inputCodes) {
+ int insertPos = 0;
+ inputCodes[insertPos++] = primaryKey;
+ const int startIndex = getStartIndexFromCoordinates(x, y);
+ for (int i = 0; i < MAX_PROXIMITY_CHARS_SIZE; ++i) {
+ const uint32_t c = mProximityCharsArray[startIndex + i];
+ if (c < KEYCODE_SPACE || c == primaryKey) {
+ continue;
+ }
+ for (int j = 0; j < KEY_COUNT; ++j) {
+ const bool onKey = isOnKey(j, x, y);
+ const int distance = squaredDistanceToEdge(j, x, y);
+ if (onKey || distance < MOST_COMMON_KEY_WIDTH_SQUARE) {
+ inputCodes[insertPos++] = c;
+ }
+ }
+ }
+ // TODO: calculate additional chars
+}
+
// TODO: Calculate nearby codes here.
void ProximityInfo::setInputParams(const int* inputCodes, const int inputLength,
const int* xCoordinates, const int* yCoordinates) {
diff --git a/native/src/proximity_info.h b/native/src/proximity_info.h
index b77c1bb0a..caabadfb6 100644
--- a/native/src/proximity_info.h
+++ b/native/src/proximity_info.h
@@ -45,13 +45,14 @@ class ProximityInfo {
ProximityInfo(const int maxProximityCharsSize, const int keyboardWidth,
const int keybaordHeight, const int gridWidth, const int gridHeight,
+ const int mostCommonkeyWidth,
const uint32_t *proximityCharsArray, const int keyCount, const int32_t *keyXCoordinates,
const int32_t *keyYCoordinates, const int32_t *keyWidths, const int32_t *keyHeights,
const int32_t *keyCharCodes, const float *sweetSpotCenterXs,
const float *sweetSpotCenterYs, const float *sweetSpotRadii);
~ProximityInfo();
bool hasSpaceProximity(const int x, const int y) const;
- void setInputParams(const int* inputCodes, const int inputLength,
+ void setInputParams(const int *inputCodes, const int inputLength,
const int *xCoordinates, const int *yCoordinates);
const int* getProximityCharsAt(const int index) const;
unsigned short getPrimaryCharAt(const int index) const;
@@ -87,12 +88,17 @@ class ProximityInfo {
// the radius of the key is assigned to zero.
return mSweetSpotRadii[keyIndex] > 0.0;
}
+ bool isOnKey(const int keyId, const int x, const int y);
+ int squaredDistanceToEdge(const int keyId, const int x, const int y);
+ void calculateNearbyKeyCodes(
+ const int x, const int y, const uint32_t primaryKey, int *inputCodes);
const int MAX_PROXIMITY_CHARS_SIZE;
const int KEYBOARD_WIDTH;
const int KEYBOARD_HEIGHT;
const int GRID_WIDTH;
const int GRID_HEIGHT;
+ const int MOST_COMMON_KEY_WIDTH_SQUARE;
const int CELL_WIDTH;
const int CELL_HEIGHT;
const int KEY_COUNT;
diff --git a/native/src/unigram_dictionary.cpp b/native/src/unigram_dictionary.cpp
index 0b646d1cd..10aa7e296 100644
--- a/native/src/unigram_dictionary.cpp
+++ b/native/src/unigram_dictionary.cpp
@@ -91,12 +91,16 @@ bool UnigramDictionary::isDigraph(const int *codes, const int i, const int codes
// codesRemain is the remaining size in codesSrc.
void UnigramDictionary::getWordWithDigraphSuggestionsRec(ProximityInfo *proximityInfo,
const int *xcoordinates, const int *ycoordinates, const int *codesBuffer,
+ int *xCoordinatesBuffer, int *yCoordinatesBuffer,
const int codesBufferSize, const int flags, const int *codesSrc,
const int codesRemain, const int currentDepth, int *codesDest, Correction *correction,
WordsPriorityQueuePool *queuePool) {
+ const int startIndex = (codesDest - codesBuffer) / MAX_PROXIMITY_CHARS;
if (currentDepth < MAX_UMLAUT_SEARCH_DEPTH) {
for (int i = 0; i < codesRemain; ++i) {
+ xCoordinatesBuffer[startIndex + i] = xcoordinates[codesBufferSize - codesRemain + i];
+ yCoordinatesBuffer[startIndex + i] = ycoordinates[codesBufferSize - codesRemain + i];
if (isDigraph(codesSrc, i, codesRemain)) {
// Found a digraph. We will try both spellings. eg. the word is "pruefen"
@@ -108,7 +112,7 @@ void UnigramDictionary::getWordWithDigraphSuggestionsRec(ProximityInfo *proximit
++i;
memcpy(codesDest, codesSrc, i * BYTES_IN_ONE_CHAR);
getWordWithDigraphSuggestionsRec(proximityInfo, xcoordinates, ycoordinates,
- codesBuffer, codesBufferSize, flags,
+ codesBuffer, xCoordinatesBuffer, yCoordinatesBuffer, codesBufferSize, flags,
codesSrc + (i + 1) * MAX_PROXIMITY_CHARS, codesRemain - i - 1,
currentDepth + 1, codesDest + i * MAX_PROXIMITY_CHARS, correction,
queuePool);
@@ -119,7 +123,7 @@ void UnigramDictionary::getWordWithDigraphSuggestionsRec(ProximityInfo *proximit
memcpy(codesDest + i * MAX_PROXIMITY_CHARS, codesSrc + i * MAX_PROXIMITY_CHARS,
BYTES_IN_ONE_CHAR);
getWordWithDigraphSuggestionsRec(proximityInfo, xcoordinates, ycoordinates,
- codesBuffer, codesBufferSize, flags,
+ codesBuffer, xCoordinatesBuffer, yCoordinatesBuffer, codesBufferSize, flags,
codesSrc + i * MAX_PROXIMITY_CHARS, codesRemain - i, currentDepth + 1,
codesDest + i * MAX_PROXIMITY_CHARS, correction, queuePool);
return;
@@ -133,11 +137,16 @@ void UnigramDictionary::getWordWithDigraphSuggestionsRec(ProximityInfo *proximit
// eg. if the word is "ueberpruefen" we'll test, in order, against
// "uberprufen", "uberpruefen", "ueberprufen", "ueberpruefen".
const unsigned int remainingBytes = BYTES_IN_ONE_CHAR * codesRemain;
- if (0 != remainingBytes)
+ if (0 != remainingBytes) {
memcpy(codesDest, codesSrc, remainingBytes);
+ memcpy(&xCoordinatesBuffer[startIndex], &xcoordinates[codesBufferSize - codesRemain],
+ sizeof(int) * codesRemain);
+ memcpy(&yCoordinatesBuffer[startIndex], &ycoordinates[codesBufferSize - codesRemain],
+ sizeof(int) * codesRemain);
+ }
- getWordSuggestions(proximityInfo, xcoordinates, ycoordinates, codesBuffer,
- (codesDest - codesBuffer) / MAX_PROXIMITY_CHARS + codesRemain, flags, correction,
+ getWordSuggestions(proximityInfo, xCoordinatesBuffer, yCoordinatesBuffer, codesBuffer,
+ startIndex + codesRemain, flags, correction,
queuePool);
}
@@ -146,11 +155,15 @@ int UnigramDictionary::getSuggestions(ProximityInfo *proximityInfo,
const int *ycoordinates, const int *codes, const int codesSize, const int flags,
unsigned short *outWords, int *frequencies) {
+ queuePool->clearAll();
Correction* masterCorrection = correction;
if (REQUIRES_GERMAN_UMLAUT_PROCESSING & flags)
{ // Incrementally tune the word and try all possibilities
int codesBuffer[getCodesBufferSize(codes, codesSize, MAX_PROXIMITY_CHARS)];
+ int xCoordinatesBuffer[codesSize];
+ int yCoordinatesBuffer[codesSize];
getWordWithDigraphSuggestionsRec(proximityInfo, xcoordinates, ycoordinates, codesBuffer,
+ xCoordinatesBuffer, yCoordinatesBuffer,
codesSize, flags, codes, codesSize, 0, codesBuffer, masterCorrection, queuePool);
} else { // Normal processing
getWordSuggestions(proximityInfo, xcoordinates, ycoordinates, codes, codesSize, flags,
@@ -192,7 +205,6 @@ void UnigramDictionary::getWordSuggestions(ProximityInfo *proximityInfo,
PROF_OPEN;
PROF_START(0);
- queuePool->clearAll();
PROF_END(0);
PROF_START(1);
diff --git a/native/src/unigram_dictionary.h b/native/src/unigram_dictionary.h
index 396a81149..12b68d71b 100644
--- a/native/src/unigram_dictionary.h
+++ b/native/src/unigram_dictionary.h
@@ -89,6 +89,7 @@ class UnigramDictionary {
bool isDigraph(const int *codes, const int i, const int codesSize) const;
void getWordWithDigraphSuggestionsRec(ProximityInfo *proximityInfo,
const int *xcoordinates, const int* ycoordinates, const int *codesBuffer,
+ int *xCoordinatesBuffer, int *yCoordinatesBuffer,
const int codesBufferSize, const int flags, const int* codesSrc,
const int codesRemain, const int currentDepth, int* codesDest, Correction *correction,
WordsPriorityQueuePool* queuePool);