Classify touches into three types.
Change-Id: I7c1d42835e0c15d596a1b66d421b0aa514ec0890main
parent
43149e454c
commit
258bfe66e0
|
@ -31,141 +31,145 @@
|
||||||
android:label="@string/subtype_en_US"
|
android:label="@string/subtype_en_US"
|
||||||
android:imeSubtypeLocale="en_US"
|
android:imeSubtypeLocale="en_US"
|
||||||
android:imeSubtypeMode="keyboard"
|
android:imeSubtypeMode="keyboard"
|
||||||
android:imeSubtypeExtraValue="TrySuppressingImeSwitcher,AsciiCapable"
|
android:imeSubtypeExtraValue="TrySuppressingImeSwitcher,AsciiCapable,SupportTouchPositionCorrection"
|
||||||
/>
|
/>
|
||||||
<subtype android:icon="@drawable/ic_subtype_keyboard"
|
<subtype android:icon="@drawable/ic_subtype_keyboard"
|
||||||
android:label="@string/subtype_en_GB"
|
android:label="@string/subtype_en_GB"
|
||||||
android:imeSubtypeLocale="en_GB"
|
android:imeSubtypeLocale="en_GB"
|
||||||
android:imeSubtypeMode="keyboard"
|
android:imeSubtypeMode="keyboard"
|
||||||
android:imeSubtypeExtraValue="TrySuppressingImeSwitcher,AsciiCapable"
|
android:imeSubtypeExtraValue="TrySuppressingImeSwitcher,AsciiCapable,SupportTouchPositionCorrection"
|
||||||
/>
|
/>
|
||||||
<subtype android:icon="@drawable/ic_subtype_keyboard"
|
<subtype android:icon="@drawable/ic_subtype_keyboard"
|
||||||
android:label="@string/subtype_generic"
|
android:label="@string/subtype_generic"
|
||||||
android:imeSubtypeLocale="ar"
|
android:imeSubtypeLocale="ar"
|
||||||
android:imeSubtypeMode="keyboard"
|
android:imeSubtypeMode="keyboard"
|
||||||
|
android:imeSubtypeExtraValue="SupportTouchPositionCorrection"
|
||||||
/>
|
/>
|
||||||
<subtype android:icon="@drawable/ic_subtype_keyboard"
|
<subtype android:icon="@drawable/ic_subtype_keyboard"
|
||||||
android:label="@string/subtype_generic"
|
android:label="@string/subtype_generic"
|
||||||
android:imeSubtypeLocale="cs"
|
android:imeSubtypeLocale="cs"
|
||||||
android:imeSubtypeMode="keyboard"
|
android:imeSubtypeMode="keyboard"
|
||||||
android:imeSubtypeExtraValue="AsciiCapable"
|
android:imeSubtypeExtraValue="AsciiCapable,SupportTouchPositionCorrection"
|
||||||
/>
|
/>
|
||||||
<subtype android:icon="@drawable/ic_subtype_keyboard"
|
<subtype android:icon="@drawable/ic_subtype_keyboard"
|
||||||
android:label="@string/subtype_generic"
|
android:label="@string/subtype_generic"
|
||||||
android:imeSubtypeLocale="da"
|
android:imeSubtypeLocale="da"
|
||||||
android:imeSubtypeMode="keyboard"
|
android:imeSubtypeMode="keyboard"
|
||||||
android:imeSubtypeExtraValue="AsciiCapable"
|
android:imeSubtypeExtraValue="AsciiCapable,SupportTouchPositionCorrection"
|
||||||
/>
|
/>
|
||||||
<subtype android:icon="@drawable/ic_subtype_keyboard"
|
<subtype android:icon="@drawable/ic_subtype_keyboard"
|
||||||
android:label="@string/subtype_generic"
|
android:label="@string/subtype_generic"
|
||||||
android:imeSubtypeLocale="de"
|
android:imeSubtypeLocale="de"
|
||||||
android:imeSubtypeMode="keyboard"
|
android:imeSubtypeMode="keyboard"
|
||||||
android:imeSubtypeExtraValue="AsciiCapable"
|
android:imeSubtypeExtraValue="AsciiCapable,SupportTouchPositionCorrection"
|
||||||
/>
|
/>
|
||||||
<subtype android:icon="@drawable/ic_subtype_keyboard"
|
<subtype android:icon="@drawable/ic_subtype_keyboard"
|
||||||
android:label="@string/subtype_de_qwerty"
|
android:label="@string/subtype_de_qwerty"
|
||||||
android:imeSubtypeLocale="de"
|
android:imeSubtypeLocale="de"
|
||||||
android:imeSubtypeMode="keyboard"
|
android:imeSubtypeMode="keyboard"
|
||||||
android:imeSubtypeExtraValue="AsciiCapable,KeyboardLocale=de_ZZ"
|
android:imeSubtypeExtraValue="AsciiCapable,KeyboardLocale=de_ZZ,SupportTouchPositionCorrection"
|
||||||
/>
|
/>
|
||||||
<subtype android:icon="@drawable/ic_subtype_keyboard"
|
<subtype android:icon="@drawable/ic_subtype_keyboard"
|
||||||
android:label="@string/subtype_generic"
|
android:label="@string/subtype_generic"
|
||||||
android:imeSubtypeLocale="es"
|
android:imeSubtypeLocale="es"
|
||||||
android:imeSubtypeMode="keyboard"
|
android:imeSubtypeMode="keyboard"
|
||||||
android:imeSubtypeExtraValue="AsciiCapable"
|
android:imeSubtypeExtraValue="AsciiCapable,SupportTouchPositionCorrection"
|
||||||
/>
|
/>
|
||||||
<subtype android:icon="@drawable/ic_subtype_keyboard"
|
<subtype android:icon="@drawable/ic_subtype_keyboard"
|
||||||
android:label="@string/subtype_generic"
|
android:label="@string/subtype_generic"
|
||||||
android:imeSubtypeLocale="fi"
|
android:imeSubtypeLocale="fi"
|
||||||
android:imeSubtypeMode="keyboard"
|
android:imeSubtypeMode="keyboard"
|
||||||
android:imeSubtypeExtraValue="AsciiCapable"
|
android:imeSubtypeExtraValue="AsciiCapable,SupportTouchPositionCorrection"
|
||||||
/>
|
/>
|
||||||
<subtype android:icon="@drawable/ic_subtype_keyboard"
|
<subtype android:icon="@drawable/ic_subtype_keyboard"
|
||||||
android:label="@string/subtype_generic"
|
android:label="@string/subtype_generic"
|
||||||
android:imeSubtypeLocale="fr"
|
android:imeSubtypeLocale="fr"
|
||||||
android:imeSubtypeMode="keyboard"
|
android:imeSubtypeMode="keyboard"
|
||||||
android:imeSubtypeExtraValue="AsciiCapable"
|
android:imeSubtypeExtraValue="AsciiCapable,SupportTouchPositionCorrection"
|
||||||
/>
|
/>
|
||||||
<subtype android:icon="@drawable/ic_subtype_keyboard"
|
<subtype android:icon="@drawable/ic_subtype_keyboard"
|
||||||
android:label="@string/subtype_generic"
|
android:label="@string/subtype_generic"
|
||||||
android:imeSubtypeLocale="fr_CA"
|
android:imeSubtypeLocale="fr_CA"
|
||||||
android:imeSubtypeMode="keyboard"
|
android:imeSubtypeMode="keyboard"
|
||||||
android:imeSubtypeExtraValue="AsciiCapable"
|
android:imeSubtypeExtraValue="AsciiCapable,SupportTouchPositionCorrection"
|
||||||
/>
|
/>
|
||||||
<subtype android:icon="@drawable/ic_subtype_keyboard"
|
<subtype android:icon="@drawable/ic_subtype_keyboard"
|
||||||
android:label="@string/subtype_generic"
|
android:label="@string/subtype_generic"
|
||||||
android:imeSubtypeLocale="fr_CH"
|
android:imeSubtypeLocale="fr_CH"
|
||||||
android:imeSubtypeMode="keyboard"
|
android:imeSubtypeMode="keyboard"
|
||||||
android:imeSubtypeExtraValue="AsciiCapable"
|
android:imeSubtypeExtraValue="AsciiCapable,SupportTouchPositionCorrection"
|
||||||
/>
|
/>
|
||||||
<subtype android:icon="@drawable/ic_subtype_keyboard"
|
<subtype android:icon="@drawable/ic_subtype_keyboard"
|
||||||
android:label="@string/subtype_generic"
|
android:label="@string/subtype_generic"
|
||||||
android:imeSubtypeLocale="hr"
|
android:imeSubtypeLocale="hr"
|
||||||
android:imeSubtypeMode="keyboard"
|
android:imeSubtypeMode="keyboard"
|
||||||
android:imeSubtypeExtraValue="AsciiCapable"
|
android:imeSubtypeExtraValue="AsciiCapable,SupportTouchPositionCorrection"
|
||||||
/>
|
/>
|
||||||
<subtype android:icon="@drawable/ic_subtype_keyboard"
|
<subtype android:icon="@drawable/ic_subtype_keyboard"
|
||||||
android:label="@string/subtype_generic"
|
android:label="@string/subtype_generic"
|
||||||
android:imeSubtypeLocale="hu"
|
android:imeSubtypeLocale="hu"
|
||||||
android:imeSubtypeMode="keyboard"
|
android:imeSubtypeMode="keyboard"
|
||||||
android:imeSubtypeExtraValue="AsciiCapable"
|
android:imeSubtypeExtraValue="AsciiCapable,SupportTouchPositionCorrection"
|
||||||
/>
|
/>
|
||||||
<subtype android:icon="@drawable/ic_subtype_keyboard"
|
<subtype android:icon="@drawable/ic_subtype_keyboard"
|
||||||
android:label="@string/subtype_generic"
|
android:label="@string/subtype_generic"
|
||||||
android:imeSubtypeLocale="it"
|
android:imeSubtypeLocale="it"
|
||||||
android:imeSubtypeMode="keyboard"
|
android:imeSubtypeMode="keyboard"
|
||||||
android:imeSubtypeExtraValue="AsciiCapable"
|
android:imeSubtypeExtraValue="AsciiCapable,SupportTouchPositionCorrection"
|
||||||
/>
|
/>
|
||||||
<!-- Java uses the deprecated "iw" code instead of the standard "he" code for Hebrew. -->
|
<!-- Java uses the deprecated "iw" code instead of the standard "he" code for Hebrew. -->
|
||||||
<subtype android:icon="@drawable/ic_subtype_keyboard"
|
<subtype android:icon="@drawable/ic_subtype_keyboard"
|
||||||
android:label="@string/subtype_generic"
|
android:label="@string/subtype_generic"
|
||||||
android:imeSubtypeLocale="iw"
|
android:imeSubtypeLocale="iw"
|
||||||
android:imeSubtypeMode="keyboard"
|
android:imeSubtypeMode="keyboard"
|
||||||
|
android:imeSubtypeExtraValue="SupportTouchPositionCorrection"
|
||||||
/>
|
/>
|
||||||
<subtype android:icon="@drawable/ic_subtype_keyboard"
|
<subtype android:icon="@drawable/ic_subtype_keyboard"
|
||||||
android:label="@string/subtype_generic"
|
android:label="@string/subtype_generic"
|
||||||
android:imeSubtypeLocale="nb"
|
android:imeSubtypeLocale="nb"
|
||||||
android:imeSubtypeMode="keyboard"
|
android:imeSubtypeMode="keyboard"
|
||||||
android:imeSubtypeExtraValue="AsciiCapable"
|
android:imeSubtypeExtraValue="AsciiCapable,SupportTouchPositionCorrection"
|
||||||
/>
|
/>
|
||||||
<subtype android:icon="@drawable/ic_subtype_keyboard"
|
<subtype android:icon="@drawable/ic_subtype_keyboard"
|
||||||
android:label="@string/subtype_generic"
|
android:label="@string/subtype_generic"
|
||||||
android:imeSubtypeLocale="nl"
|
android:imeSubtypeLocale="nl"
|
||||||
android:imeSubtypeMode="keyboard"
|
android:imeSubtypeMode="keyboard"
|
||||||
android:imeSubtypeExtraValue="AsciiCapable"
|
android:imeSubtypeExtraValue="AsciiCapable,SupportTouchPositionCorrection"
|
||||||
/>
|
/>
|
||||||
<subtype android:icon="@drawable/ic_subtype_keyboard"
|
<subtype android:icon="@drawable/ic_subtype_keyboard"
|
||||||
android:label="@string/subtype_generic"
|
android:label="@string/subtype_generic"
|
||||||
android:imeSubtypeLocale="pl"
|
android:imeSubtypeLocale="pl"
|
||||||
android:imeSubtypeMode="keyboard"
|
android:imeSubtypeMode="keyboard"
|
||||||
android:imeSubtypeExtraValue="AsciiCapable"
|
android:imeSubtypeExtraValue="AsciiCapable,SupportTouchPositionCorrection"
|
||||||
/>
|
/>
|
||||||
<subtype android:icon="@drawable/ic_subtype_keyboard"
|
<subtype android:icon="@drawable/ic_subtype_keyboard"
|
||||||
android:label="@string/subtype_generic"
|
android:label="@string/subtype_generic"
|
||||||
android:imeSubtypeLocale="pt"
|
android:imeSubtypeLocale="pt"
|
||||||
android:imeSubtypeMode="keyboard"
|
android:imeSubtypeMode="keyboard"
|
||||||
android:imeSubtypeExtraValue="AsciiCapable"
|
android:imeSubtypeExtraValue="AsciiCapable,SupportTouchPositionCorrection"
|
||||||
/>
|
/>
|
||||||
<subtype android:icon="@drawable/ic_subtype_keyboard"
|
<subtype android:icon="@drawable/ic_subtype_keyboard"
|
||||||
android:label="@string/subtype_generic"
|
android:label="@string/subtype_generic"
|
||||||
android:imeSubtypeLocale="ru"
|
android:imeSubtypeLocale="ru"
|
||||||
android:imeSubtypeMode="keyboard"
|
android:imeSubtypeMode="keyboard"
|
||||||
|
android:imeSubtypeExtraValue="SupportTouchPositionCorrection"
|
||||||
/>
|
/>
|
||||||
<subtype android:icon="@drawable/ic_subtype_keyboard"
|
<subtype android:icon="@drawable/ic_subtype_keyboard"
|
||||||
android:label="@string/subtype_generic"
|
android:label="@string/subtype_generic"
|
||||||
android:imeSubtypeLocale="sr"
|
android:imeSubtypeLocale="sr"
|
||||||
android:imeSubtypeMode="keyboard"
|
android:imeSubtypeMode="keyboard"
|
||||||
|
android:imeSubtypeExtraValue="SupportTouchPositionCorrection"
|
||||||
/>
|
/>
|
||||||
<subtype android:icon="@drawable/ic_subtype_keyboard"
|
<subtype android:icon="@drawable/ic_subtype_keyboard"
|
||||||
android:label="@string/subtype_generic"
|
android:label="@string/subtype_generic"
|
||||||
android:imeSubtypeLocale="sv"
|
android:imeSubtypeLocale="sv"
|
||||||
android:imeSubtypeMode="keyboard"
|
android:imeSubtypeMode="keyboard"
|
||||||
android:imeSubtypeExtraValue="AsciiCapable"
|
android:imeSubtypeExtraValue="AsciiCapable,SupportTouchPositionCorrection"
|
||||||
/>
|
/>
|
||||||
<subtype android:icon="@drawable/ic_subtype_keyboard"
|
<subtype android:icon="@drawable/ic_subtype_keyboard"
|
||||||
android:label="@string/subtype_generic"
|
android:label="@string/subtype_generic"
|
||||||
android:imeSubtypeLocale="tr"
|
android:imeSubtypeLocale="tr"
|
||||||
android:imeSubtypeMode="keyboard"
|
android:imeSubtypeMode="keyboard"
|
||||||
android:imeSubtypeExtraValue="AsciiCapable"
|
android:imeSubtypeExtraValue="AsciiCapable,SupportTouchPositionCorrection"
|
||||||
/>
|
/>
|
||||||
</input-method>
|
</input-method>
|
||||||
|
|
|
@ -19,6 +19,7 @@ package com.android.inputmethod.keyboard;
|
||||||
import android.graphics.Rect;
|
import android.graphics.Rect;
|
||||||
|
|
||||||
import com.android.inputmethod.keyboard.Key;
|
import com.android.inputmethod.keyboard.Key;
|
||||||
|
import com.android.inputmethod.latin.SubtypeSwitcher;
|
||||||
import com.android.inputmethod.latin.Utils;
|
import com.android.inputmethod.latin.Utils;
|
||||||
import com.android.inputmethod.latin.spellcheck.SpellCheckerProximityInfo;
|
import com.android.inputmethod.latin.spellcheck.SpellCheckerProximityInfo;
|
||||||
|
|
||||||
|
@ -31,6 +32,8 @@ public class ProximityInfo {
|
||||||
/** Number of key widths from current touch point to search for nearest keys. */
|
/** Number of key widths from current touch point to search for nearest keys. */
|
||||||
private static float SEARCH_DISTANCE = 1.2f;
|
private static float SEARCH_DISTANCE = 1.2f;
|
||||||
private static final int[] EMPTY_INT_ARRAY = new int[0];
|
private static final int[] EMPTY_INT_ARRAY = new int[0];
|
||||||
|
private static final String SUPPORT_TOUCH_POSITION_CORRECTION =
|
||||||
|
"SupportTouchPositionCorrection";
|
||||||
|
|
||||||
private final int mKeyHeight;
|
private final int mKeyHeight;
|
||||||
private final int mGridWidth;
|
private final int mGridWidth;
|
||||||
|
@ -120,8 +123,10 @@ public class ProximityInfo {
|
||||||
keyCharCodes[i] = key.mCode;
|
keyCharCodes[i] = key.mCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
final SubtypeSwitcher switcher = SubtypeSwitcher.getInstance();
|
||||||
final boolean hasTouchPositionCorrectionData =
|
final boolean hasTouchPositionCorrectionData =
|
||||||
mTouchPositionCorrectionXs != null
|
switcher.currentSubtypeContainsExtraValueKey(SUPPORT_TOUCH_POSITION_CORRECTION)
|
||||||
|
&& mTouchPositionCorrectionXs != null
|
||||||
&& mTouchPositionCorrectionYs != null
|
&& mTouchPositionCorrectionYs != null
|
||||||
&& mTouchPositionCorrectionRadii != null
|
&& mTouchPositionCorrectionRadii != null
|
||||||
&& mTouchPositionCorrectionXs.length > 0
|
&& mTouchPositionCorrectionXs.length > 0
|
||||||
|
|
|
@ -113,6 +113,9 @@ bool Correction::initProcessState(const int outputIndex) {
|
||||||
mInputIndex = mCorrectionStates[outputIndex].mInputIndex;
|
mInputIndex = mCorrectionStates[outputIndex].mInputIndex;
|
||||||
mNeedsToTraverseAllNodes = mCorrectionStates[outputIndex].mNeedsToTraverseAllNodes;
|
mNeedsToTraverseAllNodes = mCorrectionStates[outputIndex].mNeedsToTraverseAllNodes;
|
||||||
|
|
||||||
|
mEquivalentCharStrongCount = mCorrectionStates[outputIndex].mEquivalentCharStrongCount;
|
||||||
|
mEquivalentCharNormalCount = mCorrectionStates[outputIndex].mEquivalentCharNormalCount;
|
||||||
|
mEquivalentCharWeakCount = mCorrectionStates[outputIndex].mEquivalentCharWeakCount;
|
||||||
mProximityCount = mCorrectionStates[outputIndex].mProximityCount;
|
mProximityCount = mCorrectionStates[outputIndex].mProximityCount;
|
||||||
mTransposedCount = mCorrectionStates[outputIndex].mTransposedCount;
|
mTransposedCount = mCorrectionStates[outputIndex].mTransposedCount;
|
||||||
mExcessiveCount = mCorrectionStates[outputIndex].mExcessiveCount;
|
mExcessiveCount = mCorrectionStates[outputIndex].mExcessiveCount;
|
||||||
|
@ -167,6 +170,9 @@ void Correction::incrementOutputIndex() {
|
||||||
mCorrectionStates[mOutputIndex].mInputIndex = mInputIndex;
|
mCorrectionStates[mOutputIndex].mInputIndex = mInputIndex;
|
||||||
mCorrectionStates[mOutputIndex].mNeedsToTraverseAllNodes = mNeedsToTraverseAllNodes;
|
mCorrectionStates[mOutputIndex].mNeedsToTraverseAllNodes = mNeedsToTraverseAllNodes;
|
||||||
|
|
||||||
|
mCorrectionStates[mOutputIndex].mEquivalentCharStrongCount = mEquivalentCharStrongCount;
|
||||||
|
mCorrectionStates[mOutputIndex].mEquivalentCharNormalCount = mEquivalentCharNormalCount;
|
||||||
|
mCorrectionStates[mOutputIndex].mEquivalentCharWeakCount = mEquivalentCharWeakCount;
|
||||||
mCorrectionStates[mOutputIndex].mProximityCount = mProximityCount;
|
mCorrectionStates[mOutputIndex].mProximityCount = mProximityCount;
|
||||||
mCorrectionStates[mOutputIndex].mTransposedCount = mTransposedCount;
|
mCorrectionStates[mOutputIndex].mTransposedCount = mTransposedCount;
|
||||||
mCorrectionStates[mOutputIndex].mExcessiveCount = mExcessiveCount;
|
mCorrectionStates[mOutputIndex].mExcessiveCount = mExcessiveCount;
|
||||||
|
@ -208,6 +214,12 @@ Correction::CorrectionType Correction::processSkipChar(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline bool isEquivalentChar(ProximityInfo::ProximityType type) {
|
||||||
|
// 'type ProximityInfo::EQUIVALENT_CHAR_WEAK' means that
|
||||||
|
// type == ..._WEAK or type == ..._NORMAL or type == ..._STRONG.
|
||||||
|
return type <= ProximityInfo::EQUIVALENT_CHAR_WEAK;
|
||||||
|
}
|
||||||
|
|
||||||
Correction::CorrectionType Correction::processCharAndCalcState(
|
Correction::CorrectionType Correction::processCharAndCalcState(
|
||||||
const int32_t c, const bool isTerminal) {
|
const int32_t c, const bool isTerminal) {
|
||||||
const int correctionCount = (mSkippedCount + mExcessiveCount + mTransposedCount);
|
const int correctionCount = (mSkippedCount + mExcessiveCount + mTransposedCount);
|
||||||
|
@ -219,8 +231,9 @@ Correction::CorrectionType Correction::processCharAndCalcState(
|
||||||
bool incremented = false;
|
bool incremented = false;
|
||||||
if (mLastCharExceeded && mInputIndex == mInputLength - 1) {
|
if (mLastCharExceeded && mInputIndex == mInputLength - 1) {
|
||||||
// TODO: Do not check the proximity if EditDistance exceeds the threshold
|
// TODO: Do not check the proximity if EditDistance exceeds the threshold
|
||||||
const int matchId = mProximityInfo->getMatchedProximityId(mInputIndex, c, true);
|
const ProximityInfo::ProximityType matchId =
|
||||||
if (matchId == ProximityInfo::SAME_OR_ACCENTED_OR_CAPITALIZED_CHAR) {
|
mProximityInfo->getMatchedProximityId(mInputIndex, c, true);
|
||||||
|
if (isEquivalentChar(matchId)) {
|
||||||
mLastCharExceeded = false;
|
mLastCharExceeded = false;
|
||||||
--mExcessiveCount;
|
--mExcessiveCount;
|
||||||
} else if (matchId == ProximityInfo::NEAR_PROXIMITY_CHAR) {
|
} else if (matchId == ProximityInfo::NEAR_PROXIMITY_CHAR) {
|
||||||
|
@ -264,8 +277,7 @@ Correction::CorrectionType Correction::processCharAndCalcState(
|
||||||
|
|
||||||
bool secondTransposing = false;
|
bool secondTransposing = false;
|
||||||
if (mTransposedCount % 2 == 1) {
|
if (mTransposedCount % 2 == 1) {
|
||||||
if (mProximityInfo->getMatchedProximityId(mInputIndex - 1, c, false)
|
if (isEquivalentChar(mProximityInfo->getMatchedProximityId(mInputIndex - 1, c, false))) {
|
||||||
== ProximityInfo::SAME_OR_ACCENTED_OR_CAPITALIZED_CHAR) {
|
|
||||||
++mTransposedCount;
|
++mTransposedCount;
|
||||||
secondTransposing = true;
|
secondTransposing = true;
|
||||||
} else if (mCorrectionStates[mOutputIndex].mExceeding) {
|
} else if (mCorrectionStates[mOutputIndex].mExceeding) {
|
||||||
|
@ -286,8 +298,8 @@ Correction::CorrectionType Correction::processCharAndCalcState(
|
||||||
|
|
||||||
// TODO: Change the limit if we'll allow two or more proximity chars with corrections
|
// TODO: Change the limit if we'll allow two or more proximity chars with corrections
|
||||||
const bool checkProximityChars = noCorrectionsHappenedSoFar || mProximityCount == 0;
|
const bool checkProximityChars = noCorrectionsHappenedSoFar || mProximityCount == 0;
|
||||||
const int matchedProximityCharId = secondTransposing
|
const ProximityInfo::ProximityType matchedProximityCharId = secondTransposing
|
||||||
? ProximityInfo::SAME_OR_ACCENTED_OR_CAPITALIZED_CHAR
|
? ProximityInfo::EQUIVALENT_CHAR_NORMAL
|
||||||
: mProximityInfo->getMatchedProximityId(mInputIndex, c, checkProximityChars);
|
: mProximityInfo->getMatchedProximityId(mInputIndex, c, checkProximityChars);
|
||||||
|
|
||||||
if (ProximityInfo::UNRELATED_CHAR == matchedProximityCharId) {
|
if (ProximityInfo::UNRELATED_CHAR == matchedProximityCharId) {
|
||||||
|
@ -297,19 +309,18 @@ Correction::CorrectionType Correction::processCharAndCalcState(
|
||||||
// here refers to the previous state.
|
// here refers to the previous state.
|
||||||
if (canTryCorrection && mCorrectionStates[mOutputIndex].mProximityMatching
|
if (canTryCorrection && mCorrectionStates[mOutputIndex].mProximityMatching
|
||||||
&& mCorrectionStates[mOutputIndex].mExceeding
|
&& mCorrectionStates[mOutputIndex].mExceeding
|
||||||
&& mProximityInfo->getMatchedProximityId(mInputIndex, mWord[mOutputIndex], false)
|
&& isEquivalentChar(mProximityInfo->getMatchedProximityId(
|
||||||
== ProximityInfo::SAME_OR_ACCENTED_OR_CAPITALIZED_CHAR) {
|
mInputIndex, mWord[mOutputIndex], false))) {
|
||||||
// Conversion p->e
|
// Conversion p->e
|
||||||
++mExcessiveCount;
|
++mExcessiveCount;
|
||||||
--mProximityCount;
|
--mProximityCount;
|
||||||
} else if (mInputIndex < mInputLength - 1 && mOutputIndex > 0 && mTransposedCount > 0
|
} else if (mInputIndex < mInputLength - 1 && mOutputIndex > 0 && mTransposedCount > 0
|
||||||
&& !mCorrectionStates[mOutputIndex].mTransposing
|
&& !mCorrectionStates[mOutputIndex].mTransposing
|
||||||
&& mCorrectionStates[mOutputIndex - 1].mTransposing
|
&& mCorrectionStates[mOutputIndex - 1].mTransposing
|
||||||
&& mProximityInfo->getMatchedProximityId(
|
&& isEquivalentChar(mProximityInfo->getMatchedProximityId(
|
||||||
mInputIndex, mWord[mOutputIndex - 1], false)
|
mInputIndex, mWord[mOutputIndex - 1], false))
|
||||||
== ProximityInfo::SAME_OR_ACCENTED_OR_CAPITALIZED_CHAR
|
&& isEquivalentChar(
|
||||||
&& mProximityInfo->getMatchedProximityId(mInputIndex + 1, c, false)
|
mProximityInfo->getMatchedProximityId(mInputIndex + 1, c, false))) {
|
||||||
== ProximityInfo::SAME_OR_ACCENTED_OR_CAPITALIZED_CHAR) {
|
|
||||||
// Conversion t->e
|
// Conversion t->e
|
||||||
// Example:
|
// Example:
|
||||||
// occaisional -> occa sional
|
// occaisional -> occa sional
|
||||||
|
@ -320,8 +331,8 @@ Correction::CorrectionType Correction::processCharAndCalcState(
|
||||||
} else if (mOutputIndex > 0 && mInputIndex > 0 && mTransposedCount > 0
|
} else if (mOutputIndex > 0 && mInputIndex > 0 && mTransposedCount > 0
|
||||||
&& !mCorrectionStates[mOutputIndex].mTransposing
|
&& !mCorrectionStates[mOutputIndex].mTransposing
|
||||||
&& mCorrectionStates[mOutputIndex - 1].mTransposing
|
&& mCorrectionStates[mOutputIndex - 1].mTransposing
|
||||||
&& mProximityInfo->getMatchedProximityId(mInputIndex - 1, c, false)
|
&& isEquivalentChar(
|
||||||
== ProximityInfo::SAME_OR_ACCENTED_OR_CAPITALIZED_CHAR) {
|
mProximityInfo->getMatchedProximityId(mInputIndex - 1, c, false))) {
|
||||||
// Conversion t->s
|
// Conversion t->s
|
||||||
// Example:
|
// Example:
|
||||||
// chcolate -> chocolate
|
// chcolate -> chocolate
|
||||||
|
@ -332,8 +343,8 @@ Correction::CorrectionType Correction::processCharAndCalcState(
|
||||||
} else if (canTryCorrection && mInputIndex > 0
|
} else if (canTryCorrection && mInputIndex > 0
|
||||||
&& mCorrectionStates[mOutputIndex].mProximityMatching
|
&& mCorrectionStates[mOutputIndex].mProximityMatching
|
||||||
&& mCorrectionStates[mOutputIndex].mSkipping
|
&& mCorrectionStates[mOutputIndex].mSkipping
|
||||||
&& mProximityInfo->getMatchedProximityId(mInputIndex - 1, c, false)
|
&& isEquivalentChar(
|
||||||
== ProximityInfo::SAME_OR_ACCENTED_OR_CAPITALIZED_CHAR) {
|
mProximityInfo->getMatchedProximityId(mInputIndex - 1, c, false))) {
|
||||||
// Conversion p->s
|
// Conversion p->s
|
||||||
// Note: This logic tries saving cases like contrst --> contrast -- "a" is one of
|
// Note: This logic tries saving cases like contrst --> contrast -- "a" is one of
|
||||||
// proximity chars of "s", but it should rather be handled as a skipped char.
|
// proximity chars of "s", but it should rather be handled as a skipped char.
|
||||||
|
@ -341,8 +352,8 @@ Correction::CorrectionType Correction::processCharAndCalcState(
|
||||||
--mProximityCount;
|
--mProximityCount;
|
||||||
return processSkipChar(c, isTerminal, false);
|
return processSkipChar(c, isTerminal, false);
|
||||||
} else if ((mExceeding || mTransposing) && mInputIndex - 1 < mInputLength
|
} else if ((mExceeding || mTransposing) && mInputIndex - 1 < mInputLength
|
||||||
&& mProximityInfo->getMatchedProximityId(mInputIndex + 1, c, false)
|
&& isEquivalentChar(
|
||||||
== ProximityInfo::SAME_OR_ACCENTED_OR_CAPITALIZED_CHAR) {
|
mProximityInfo->getMatchedProximityId(mInputIndex + 1, c, false))) {
|
||||||
// 1.2. Excessive or transpose correction
|
// 1.2. Excessive or transpose correction
|
||||||
if (mTransposing) {
|
if (mTransposing) {
|
||||||
++mTransposedCount;
|
++mTransposedCount;
|
||||||
|
@ -362,14 +373,28 @@ Correction::CorrectionType Correction::processCharAndCalcState(
|
||||||
}
|
}
|
||||||
return UNRELATED;
|
return UNRELATED;
|
||||||
}
|
}
|
||||||
} else if (secondTransposing
|
} else if (secondTransposing) {
|
||||||
|| ProximityInfo::SAME_OR_ACCENTED_OR_CAPITALIZED_CHAR == matchedProximityCharId) {
|
|
||||||
// If inputIndex is greater than mInputLength, that means there is no
|
// If inputIndex is greater than mInputLength, that means there is no
|
||||||
// proximity chars. So, we don't need to check proximity.
|
// proximity chars. So, we don't need to check proximity.
|
||||||
mMatching = true;
|
mMatching = true;
|
||||||
|
} else if (isEquivalentChar(matchedProximityCharId)) {
|
||||||
|
mMatching = true;
|
||||||
|
switch (matchedProximityCharId) {
|
||||||
|
case ProximityInfo::EQUIVALENT_CHAR_STRONG:
|
||||||
|
++mEquivalentCharStrongCount;
|
||||||
|
break;
|
||||||
|
case ProximityInfo::EQUIVALENT_CHAR_NORMAL:
|
||||||
|
++mEquivalentCharNormalCount;
|
||||||
|
break;
|
||||||
|
case ProximityInfo::EQUIVALENT_CHAR_WEAK:
|
||||||
|
++mEquivalentCharWeakCount;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
assert(false);
|
||||||
|
}
|
||||||
} else if (ProximityInfo::NEAR_PROXIMITY_CHAR == matchedProximityCharId) {
|
} else if (ProximityInfo::NEAR_PROXIMITY_CHAR == matchedProximityCharId) {
|
||||||
mProximityMatching = true;
|
mProximityMatching = true;
|
||||||
incrementProximityCount();
|
++mProximityCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
mWord[mOutputIndex] = c;
|
mWord[mOutputIndex] = c;
|
||||||
|
|
|
@ -102,11 +102,6 @@ private:
|
||||||
inline CorrectionType processSkipChar(
|
inline CorrectionType processSkipChar(
|
||||||
const int32_t c, const bool isTerminal, const bool inputIndexIncremented);
|
const int32_t c, const bool isTerminal, const bool inputIndexIncremented);
|
||||||
|
|
||||||
// TODO: remove
|
|
||||||
inline void incrementProximityCount() {
|
|
||||||
++mProximityCount;
|
|
||||||
}
|
|
||||||
|
|
||||||
const int TYPED_LETTER_MULTIPLIER;
|
const int TYPED_LETTER_MULTIPLIER;
|
||||||
const int FULL_WORD_MULTIPLIER;
|
const int FULL_WORD_MULTIPLIER;
|
||||||
const ProximityInfo *mProximityInfo;
|
const ProximityInfo *mProximityInfo;
|
||||||
|
@ -130,6 +125,9 @@ private:
|
||||||
int mOutputIndex;
|
int mOutputIndex;
|
||||||
int mInputIndex;
|
int mInputIndex;
|
||||||
|
|
||||||
|
int mEquivalentCharStrongCount;
|
||||||
|
int mEquivalentCharNormalCount;
|
||||||
|
int mEquivalentCharWeakCount;
|
||||||
int mProximityCount;
|
int mProximityCount;
|
||||||
int mExcessiveCount;
|
int mExcessiveCount;
|
||||||
int mTransposedCount;
|
int mTransposedCount;
|
||||||
|
|
|
@ -29,6 +29,9 @@ struct CorrectionState {
|
||||||
uint16_t mChildCount;
|
uint16_t mChildCount;
|
||||||
uint8_t mInputIndex;
|
uint8_t mInputIndex;
|
||||||
|
|
||||||
|
uint8_t mEquivalentCharStrongCount;
|
||||||
|
uint8_t mEquivalentCharNormalCount;
|
||||||
|
uint8_t mEquivalentCharWeakCount;
|
||||||
uint8_t mProximityCount;
|
uint8_t mProximityCount;
|
||||||
uint8_t mTransposedCount;
|
uint8_t mTransposedCount;
|
||||||
uint8_t mExcessiveCount;
|
uint8_t mExcessiveCount;
|
||||||
|
@ -63,7 +66,9 @@ inline static void initCorrectionState(CorrectionState *state, const int rootPos
|
||||||
state->mExcessivePos = -1;
|
state->mExcessivePos = -1;
|
||||||
state->mSkipPos = -1;
|
state->mSkipPos = -1;
|
||||||
|
|
||||||
|
state->mEquivalentCharStrongCount = 0;
|
||||||
|
state->mEquivalentCharNormalCount = 0;
|
||||||
|
state->mEquivalentCharWeakCount = 0;
|
||||||
state->mProximityCount = 0;
|
state->mProximityCount = 0;
|
||||||
state->mTransposedCount = 0;
|
state->mTransposedCount = 0;
|
||||||
state->mExcessiveCount = 0;
|
state->mExcessiveCount = 0;
|
||||||
|
|
|
@ -165,6 +165,8 @@ static void dumpWord(const unsigned short* word, const int length) {
|
||||||
|
|
||||||
#define KEYCODE_SPACE ' '
|
#define KEYCODE_SPACE ' '
|
||||||
|
|
||||||
|
#define CALIBRATE_SCORE_BY_TOUCH_COORDINATES false
|
||||||
|
|
||||||
#define SUGGEST_WORDS_WITH_MISSING_CHARACTER true
|
#define SUGGEST_WORDS_WITH_MISSING_CHARACTER true
|
||||||
#define SUGGEST_WORDS_WITH_MISSING_SPACE_CHARACTER true
|
#define SUGGEST_WORDS_WITH_MISSING_SPACE_CHARACTER true
|
||||||
#define SUGGEST_WORDS_WITH_EXCESSIVE_CHARACTER true
|
#define SUGGEST_WORDS_WITH_EXCESSIVE_CHARACTER true
|
||||||
|
@ -204,4 +206,7 @@ static void dumpWord(const unsigned short* word, const int length) {
|
||||||
#define min(a,b) ((a)<(b)?(a):(b))
|
#define min(a,b) ((a)<(b)?(a):(b))
|
||||||
#define max(a,b) ((a)>(b)?(a):(b))
|
#define max(a,b) ((a)>(b)?(a):(b))
|
||||||
|
|
||||||
|
// The ratio of neutral area radius to sweet spot radius.
|
||||||
|
#define NEUTRAL_AREA_RADIUS_RATIO 1.3f
|
||||||
|
|
||||||
#endif // LATINIME_DEFINES_H
|
#endif // LATINIME_DEFINES_H
|
||||||
|
|
|
@ -43,7 +43,8 @@ ProximityInfo::ProximityInfo(const int maxProximityCharsSize, const int keyboard
|
||||||
KEYBOARD_HEIGHT(keyboardHeight), GRID_WIDTH(gridWidth), GRID_HEIGHT(gridHeight),
|
KEYBOARD_HEIGHT(keyboardHeight), GRID_WIDTH(gridWidth), GRID_HEIGHT(gridHeight),
|
||||||
CELL_WIDTH((keyboardWidth + gridWidth - 1) / gridWidth),
|
CELL_WIDTH((keyboardWidth + gridWidth - 1) / gridWidth),
|
||||||
CELL_HEIGHT((keyboardHeight + gridHeight - 1) / gridHeight),
|
CELL_HEIGHT((keyboardHeight + gridHeight - 1) / gridHeight),
|
||||||
KEY_COUNT(min(keyCount, MAX_KEY_COUNT_IN_A_KEYBOARD)) {
|
KEY_COUNT(min(keyCount, MAX_KEY_COUNT_IN_A_KEYBOARD)),
|
||||||
|
mInputXCoordinates(NULL), mInputYCoordinates(NULL) {
|
||||||
const int len = GRID_WIDTH * GRID_HEIGHT * MAX_PROXIMITY_CHARS_SIZE;
|
const int len = GRID_WIDTH * GRID_HEIGHT * MAX_PROXIMITY_CHARS_SIZE;
|
||||||
mProximityCharsArray = new uint32_t[len];
|
mProximityCharsArray = new uint32_t[len];
|
||||||
if (DEBUG_PROXIMITY_INFO) {
|
if (DEBUG_PROXIMITY_INFO) {
|
||||||
|
@ -103,8 +104,11 @@ bool ProximityInfo::hasSpaceProximity(const int x, const int y) const {
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Calculate nearby codes here.
|
// TODO: Calculate nearby codes here.
|
||||||
void ProximityInfo::setInputParams(const int* inputCodes, const int inputLength) {
|
void ProximityInfo::setInputParams(const int* inputCodes, const int inputLength,
|
||||||
|
const int* xCoordinates, const int* yCoordinates) {
|
||||||
mInputCodes = inputCodes;
|
mInputCodes = inputCodes;
|
||||||
|
mInputXCoordinates = xCoordinates;
|
||||||
|
mInputYCoordinates = yCoordinates;
|
||||||
mInputLength = inputLength;
|
mInputLength = inputLength;
|
||||||
for (int i = 0; i < inputLength; ++i) {
|
for (int i = 0; i < inputLength; ++i) {
|
||||||
mPrimaryInputWord[i] = getPrimaryCharAt(i);
|
mPrimaryInputWord[i] = getPrimaryCharAt(i);
|
||||||
|
@ -158,19 +162,37 @@ bool ProximityInfo::existsAdjacentProximityChars(const int index) const {
|
||||||
ProximityInfo::ProximityType ProximityInfo::getMatchedProximityId(
|
ProximityInfo::ProximityType ProximityInfo::getMatchedProximityId(
|
||||||
const int index, const unsigned short c, const bool checkProximityChars) const {
|
const int index, const unsigned short c, const bool checkProximityChars) const {
|
||||||
const int *currentChars = getProximityCharsAt(index);
|
const int *currentChars = getProximityCharsAt(index);
|
||||||
|
const int firstChar = currentChars[0];
|
||||||
const unsigned short baseLowerC = Dictionary::toBaseLowerCase(c);
|
const unsigned short baseLowerC = Dictionary::toBaseLowerCase(c);
|
||||||
|
|
||||||
// The first char in the array is what user typed. If it matches right away,
|
// The first char in the array is what user typed. If it matches right away,
|
||||||
// that means the user typed that same char for this pos.
|
// that means the user typed that same char for this pos.
|
||||||
if (currentChars[0] == baseLowerC || currentChars[0] == c)
|
if (firstChar == baseLowerC || firstChar == c) {
|
||||||
return SAME_OR_ACCENTED_OR_CAPITALIZED_CHAR;
|
if (CALIBRATE_SCORE_BY_TOUCH_COORDINATES) {
|
||||||
|
const SweetSpotType result = calculateSweetSpotType(index, baseLowerC);
|
||||||
|
switch (result) {
|
||||||
|
case UNKNOWN:
|
||||||
|
return EQUIVALENT_CHAR_NORMAL;
|
||||||
|
case IN_SWEET_SPOT:
|
||||||
|
return EQUIVALENT_CHAR_STRONG;
|
||||||
|
case IN_NEUTRAL_AREA:
|
||||||
|
return EQUIVALENT_CHAR_NORMAL;
|
||||||
|
case OUT_OF_NEUTRAL_AREA:
|
||||||
|
return EQUIVALENT_CHAR_WEAK;
|
||||||
|
default:
|
||||||
|
assert(false);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return EQUIVALENT_CHAR_NORMAL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (!checkProximityChars) return UNRELATED_CHAR;
|
if (!checkProximityChars) return UNRELATED_CHAR;
|
||||||
|
|
||||||
// If the non-accented, lowercased version of that first character matches c,
|
// If the non-accented, lowercased version of that first character matches c,
|
||||||
// then we have a non-accented version of the accented character the user
|
// then we have a non-accented version of the accented character the user
|
||||||
// typed. Treat it as a close char.
|
// typed. Treat it as a close char.
|
||||||
if (Dictionary::toBaseLowerCase(currentChars[0]) == baseLowerC)
|
if (Dictionary::toBaseLowerCase(firstChar) == baseLowerC)
|
||||||
return NEAR_PROXIMITY_CHAR;
|
return NEAR_PROXIMITY_CHAR;
|
||||||
|
|
||||||
// Not an exact nor an accent-alike match: search the list of close keys
|
// Not an exact nor an accent-alike match: search the list of close keys
|
||||||
|
@ -185,6 +207,38 @@ ProximityInfo::ProximityType ProximityInfo::getMatchedProximityId(
|
||||||
return UNRELATED_CHAR;
|
return UNRELATED_CHAR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline float square(const float x) { return x * x; }
|
||||||
|
|
||||||
|
ProximityInfo::SweetSpotType ProximityInfo::calculateSweetSpotType(
|
||||||
|
int index, unsigned short baseLowerC) const {
|
||||||
|
if (KEY_COUNT == 0 || !mInputXCoordinates || !mInputYCoordinates
|
||||||
|
|| baseLowerC > MAX_CHAR_CODE) {
|
||||||
|
return UNKNOWN;
|
||||||
|
}
|
||||||
|
const int keyIndex = mCodeToKeyIndex[baseLowerC];
|
||||||
|
if (keyIndex < 0) {
|
||||||
|
return UNKNOWN;
|
||||||
|
}
|
||||||
|
const float sweetSpotRadius = mSweetSpotRadii[keyIndex];
|
||||||
|
if (sweetSpotRadius <= 0.0) {
|
||||||
|
return UNKNOWN;
|
||||||
|
}
|
||||||
|
const float sweetSpotCenterX = mSweetSpotCenterXs[keyIndex];
|
||||||
|
const float sweetSpotCenterY = mSweetSpotCenterXs[keyIndex];
|
||||||
|
const float inputX = (float)mInputXCoordinates[index];
|
||||||
|
const float inputY = (float)mInputYCoordinates[index];
|
||||||
|
const float squaredDistance =
|
||||||
|
square(inputX - sweetSpotCenterX) + square(inputY - sweetSpotCenterY);
|
||||||
|
const float squaredSweetSpotRadius = square(sweetSpotRadius);
|
||||||
|
if (squaredDistance <= squaredSweetSpotRadius) {
|
||||||
|
return IN_SWEET_SPOT;
|
||||||
|
}
|
||||||
|
if (squaredDistance <= square(NEUTRAL_AREA_RADIUS_RATIO) * squaredSweetSpotRadius) {
|
||||||
|
return IN_NEUTRAL_AREA;
|
||||||
|
}
|
||||||
|
return OUT_OF_NEUTRAL_AREA;
|
||||||
|
}
|
||||||
|
|
||||||
bool ProximityInfo::sameAsTyped(const unsigned short *word, int length) const {
|
bool ProximityInfo::sameAsTyped(const unsigned short *word, int length) const {
|
||||||
if (length != mInputLength) {
|
if (length != mInputLength) {
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -27,10 +27,18 @@ class Correction;
|
||||||
|
|
||||||
class ProximityInfo {
|
class ProximityInfo {
|
||||||
public:
|
public:
|
||||||
typedef enum { // Used as a return value for character comparison
|
// Used as a return value for character comparison
|
||||||
SAME_OR_ACCENTED_OR_CAPITALIZED_CHAR, // Same char, possibly with different case or accent
|
typedef enum {
|
||||||
NEAR_PROXIMITY_CHAR, // It is a char located nearby on the keyboard
|
// Same char, possibly with different case or accent, and in the sweet spot of the char
|
||||||
UNRELATED_CHAR // It is an unrelated char
|
EQUIVALENT_CHAR_STRONG,
|
||||||
|
// Same char, possibly with different case or accent, and in the outer sweet spot
|
||||||
|
EQUIVALENT_CHAR_NORMAL,
|
||||||
|
// Same char, possibly with different case or accent, and in the hit box of the char
|
||||||
|
EQUIVALENT_CHAR_WEAK,
|
||||||
|
// It is a char located nearby on the keyboard
|
||||||
|
NEAR_PROXIMITY_CHAR,
|
||||||
|
// It is an unrelated char
|
||||||
|
UNRELATED_CHAR
|
||||||
} ProximityType;
|
} ProximityType;
|
||||||
|
|
||||||
ProximityInfo(const int maxProximityCharsSize, const int keyboardWidth,
|
ProximityInfo(const int maxProximityCharsSize, const int keyboardWidth,
|
||||||
|
@ -41,7 +49,8 @@ public:
|
||||||
const float *sweetSpotCenterYs, const float *sweetSpotRadii);
|
const float *sweetSpotCenterYs, const float *sweetSpotRadii);
|
||||||
~ProximityInfo();
|
~ProximityInfo();
|
||||||
bool hasSpaceProximity(const int x, const int y) const;
|
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;
|
const int* getProximityCharsAt(const int index) const;
|
||||||
unsigned short getPrimaryCharAt(const int index) const;
|
unsigned short getPrimaryCharAt(const int index) const;
|
||||||
bool existsCharInProximityAt(const int index, const int c) const;
|
bool existsCharInProximityAt(const int index, const int c) const;
|
||||||
|
@ -59,8 +68,20 @@ private:
|
||||||
// The upper limit of the char code in mCodeToKeyIndex
|
// The upper limit of the char code in mCodeToKeyIndex
|
||||||
static const int MAX_CHAR_CODE = 127;
|
static const int MAX_CHAR_CODE = 127;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
// cannot figure out the sweet spot type
|
||||||
|
UNKNOWN,
|
||||||
|
// touch position is out of neutral area of the given char
|
||||||
|
OUT_OF_NEUTRAL_AREA,
|
||||||
|
// touch position is in the neutral area of the given char
|
||||||
|
IN_NEUTRAL_AREA,
|
||||||
|
// touch position is in the sweet spot of the given char
|
||||||
|
IN_SWEET_SPOT
|
||||||
|
} SweetSpotType;
|
||||||
|
|
||||||
int getStartIndexFromCoordinates(const int x, const int y) const;
|
int getStartIndexFromCoordinates(const int x, const int y) const;
|
||||||
void initializeCodeToKeyIndex();
|
void initializeCodeToKeyIndex();
|
||||||
|
SweetSpotType calculateSweetSpotType(int index, unsigned short baseLowerC) const;
|
||||||
const int MAX_PROXIMITY_CHARS_SIZE;
|
const int MAX_PROXIMITY_CHARS_SIZE;
|
||||||
const int KEYBOARD_WIDTH;
|
const int KEYBOARD_WIDTH;
|
||||||
const int KEYBOARD_HEIGHT;
|
const int KEYBOARD_HEIGHT;
|
||||||
|
@ -70,6 +91,8 @@ private:
|
||||||
const int CELL_HEIGHT;
|
const int CELL_HEIGHT;
|
||||||
const int KEY_COUNT;
|
const int KEY_COUNT;
|
||||||
const int *mInputCodes;
|
const int *mInputCodes;
|
||||||
|
const int *mInputXCoordinates;
|
||||||
|
const int *mInputYCoordinates;
|
||||||
uint32_t *mProximityCharsArray;
|
uint32_t *mProximityCharsArray;
|
||||||
int32_t mKeyXCoordinates[MAX_KEY_COUNT_IN_A_KEYBOARD];
|
int32_t mKeyXCoordinates[MAX_KEY_COUNT_IN_A_KEYBOARD];
|
||||||
int32_t mKeyYCoordinates[MAX_KEY_COUNT_IN_A_KEYBOARD];
|
int32_t mKeyYCoordinates[MAX_KEY_COUNT_IN_A_KEYBOARD];
|
||||||
|
|
|
@ -238,8 +238,8 @@ void UnigramDictionary::getWordSuggestions(ProximityInfo *proximityInfo,
|
||||||
PROF_END(6);
|
PROF_END(6);
|
||||||
}
|
}
|
||||||
|
|
||||||
void UnigramDictionary::initSuggestions(ProximityInfo *proximityInfo, const int *xcoordinates,
|
void UnigramDictionary::initSuggestions(ProximityInfo *proximityInfo, const int *xCoordinates,
|
||||||
const int *ycoordinates, const int *codes, const int codesSize,
|
const int *yCoordinates, const int *codes, const int codesSize,
|
||||||
unsigned short *outWords, int *frequencies) {
|
unsigned short *outWords, int *frequencies) {
|
||||||
if (DEBUG_DICT) {
|
if (DEBUG_DICT) {
|
||||||
LOGI("initSuggest");
|
LOGI("initSuggest");
|
||||||
|
@ -247,7 +247,7 @@ void UnigramDictionary::initSuggestions(ProximityInfo *proximityInfo, const int
|
||||||
mFrequencies = frequencies;
|
mFrequencies = frequencies;
|
||||||
mOutputChars = outWords;
|
mOutputChars = outWords;
|
||||||
mInputLength = codesSize;
|
mInputLength = codesSize;
|
||||||
proximityInfo->setInputParams(codes, codesSize);
|
proximityInfo->setInputParams(codes, codesSize, xCoordinates, yCoordinates);
|
||||||
mProximityInfo = proximityInfo;
|
mProximityInfo = proximityInfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue