diff --git a/java/src/com/android/inputmethod/latin/SuggestedWords.java b/java/src/com/android/inputmethod/latin/SuggestedWords.java index 30dd51aed..df8db0cd2 100644 --- a/java/src/com/android/inputmethod/latin/SuggestedWords.java +++ b/java/src/com/android/inputmethod/latin/SuggestedWords.java @@ -252,6 +252,7 @@ public class SuggestedWords { public static final int KIND_FLAG_POSSIBLY_OFFENSIVE = 0x80000000; public static final int KIND_FLAG_EXACT_MATCH = 0x40000000; public static final int KIND_FLAG_EXACT_MATCH_WITH_INTENTIONAL_OMISSION = 0x20000000; + public static final int KIND_FLAG_APPROPRIATE_FOR_AUTO_CORRECTION = 0x10000000; public final String mWord; // The completion info from the application. Null for suggestions that don't come from @@ -333,6 +334,10 @@ public class SuggestedWords { return (mKindAndFlags & KIND_FLAG_EXACT_MATCH_WITH_INTENTIONAL_OMISSION) != 0; } + public boolean isAprapreateForAutoCorrection() { + return (mKindAndFlags & KIND_FLAG_APPROPRIATE_FOR_AUTO_CORRECTION) != 0; + } + public void setDebugString(final String str) { if (null == str) throw new NullPointerException("Debug info is null"); mDebugString = str; diff --git a/java/src/com/android/inputmethod/latin/utils/AutoCorrectionUtils.java b/java/src/com/android/inputmethod/latin/utils/AutoCorrectionUtils.java index 2fd257922..c9ecade91 100644 --- a/java/src/com/android/inputmethod/latin/utils/AutoCorrectionUtils.java +++ b/java/src/com/android/inputmethod/latin/utils/AutoCorrectionUtils.java @@ -36,6 +36,10 @@ public final class AutoCorrectionUtils { if (suggestion.isKindOf(SuggestedWordInfo.KIND_WHITELIST)) { return true; } + // TODO: return suggestion.isAprapreateForAutoCorrection(); + if (!suggestion.isAprapreateForAutoCorrection()) { + return false; + } final int autoCorrectionSuggestionScore = suggestion.mScore; // TODO: when the normalized score of the first suggestion is nearly equals to // the normalized score of the second suggestion, behave less aggressive. diff --git a/native/jni/src/suggest/core/dictionary/dictionary.h b/native/jni/src/suggest/core/dictionary/dictionary.h index a5e986d15..b1774371b 100644 --- a/native/jni/src/suggest/core/dictionary/dictionary.h +++ b/native/jni/src/suggest/core/dictionary/dictionary.h @@ -60,6 +60,7 @@ class Dictionary { static const int KIND_FLAG_POSSIBLY_OFFENSIVE = 0x80000000; static const int KIND_FLAG_EXACT_MATCH = 0x40000000; static const int KIND_FLAG_EXACT_MATCH_WITH_INTENTIONAL_OMISSION = 0x20000000; + static const int KIND_FLAG_APPROPRIATE_FOR_AUTOCORRECTION = 0x10000000; Dictionary(JNIEnv *env, DictionaryStructureWithBufferPolicy::StructurePolicyPtr dictionaryStructureWithBufferPolicy); diff --git a/native/jni/src/suggest/core/dictionary/error_type_utils.cpp b/native/jni/src/suggest/core/dictionary/error_type_utils.cpp index 8f07ce275..61093e174 100644 --- a/native/jni/src/suggest/core/dictionary/error_type_utils.cpp +++ b/native/jni/src/suggest/core/dictionary/error_type_utils.cpp @@ -21,13 +21,14 @@ namespace latinime { const ErrorTypeUtils::ErrorType ErrorTypeUtils::NOT_AN_ERROR = 0x0; const ErrorTypeUtils::ErrorType ErrorTypeUtils::MATCH_WITH_WRONG_CASE = 0x1; const ErrorTypeUtils::ErrorType ErrorTypeUtils::MATCH_WITH_MISSING_ACCENT = 0x2; -const ErrorTypeUtils::ErrorType ErrorTypeUtils::MATCH_WITH_WRONG_ACCENT = 0x4; -const ErrorTypeUtils::ErrorType ErrorTypeUtils::MATCH_WITH_DIGRAPH = 0x8; -const ErrorTypeUtils::ErrorType ErrorTypeUtils::INTENTIONAL_OMISSION = 0x10; -const ErrorTypeUtils::ErrorType ErrorTypeUtils::EDIT_CORRECTION = 0x20; -const ErrorTypeUtils::ErrorType ErrorTypeUtils::PROXIMITY_CORRECTION = 0x40; -const ErrorTypeUtils::ErrorType ErrorTypeUtils::COMPLETION = 0x80; -const ErrorTypeUtils::ErrorType ErrorTypeUtils::NEW_WORD = 0x100; +const ErrorTypeUtils::ErrorType ErrorTypeUtils::MATCH_WITH_MISSING_EXPLICIT_ACCENT = 0x4; +const ErrorTypeUtils::ErrorType ErrorTypeUtils::MATCH_WITH_WRONG_ACCENT = 0x8; +const ErrorTypeUtils::ErrorType ErrorTypeUtils::MATCH_WITH_DIGRAPH = 0x10; +const ErrorTypeUtils::ErrorType ErrorTypeUtils::INTENTIONAL_OMISSION = 0x20; +const ErrorTypeUtils::ErrorType ErrorTypeUtils::EDIT_CORRECTION = 0x40; +const ErrorTypeUtils::ErrorType ErrorTypeUtils::PROXIMITY_CORRECTION = 0x80; +const ErrorTypeUtils::ErrorType ErrorTypeUtils::COMPLETION = 0x100; +const ErrorTypeUtils::ErrorType ErrorTypeUtils::NEW_WORD = 0x200; const ErrorTypeUtils::ErrorType ErrorTypeUtils::ERRORS_TREATED_AS_AN_EXACT_MATCH = NOT_AN_ERROR | MATCH_WITH_WRONG_CASE | MATCH_WITH_MISSING_ACCENT | MATCH_WITH_DIGRAPH; diff --git a/native/jni/src/suggest/core/dictionary/error_type_utils.h b/native/jni/src/suggest/core/dictionary/error_type_utils.h index e92c509fa..75111ba75 100644 --- a/native/jni/src/suggest/core/dictionary/error_type_utils.h +++ b/native/jni/src/suggest/core/dictionary/error_type_utils.h @@ -32,6 +32,7 @@ class ErrorTypeUtils { static const ErrorType NOT_AN_ERROR; static const ErrorType MATCH_WITH_WRONG_CASE; static const ErrorType MATCH_WITH_MISSING_ACCENT; + static const ErrorType MATCH_WITH_MISSING_EXPLICIT_ACCENT; static const ErrorType MATCH_WITH_WRONG_ACCENT; static const ErrorType MATCH_WITH_DIGRAPH; // Treat error as an intentional omission when the CorrectionType is omission and the node can @@ -61,6 +62,10 @@ class ErrorTypeUtils { & ~ERRORS_TREATED_AS_AN_EXACT_MATCH_WITH_INTENTIONAL_OMISSION) == 0; } + static bool isMissingExplicitAccent(const ErrorType errorType) { + return (errorType & MATCH_WITH_MISSING_EXPLICIT_ACCENT) != 0; + } + static bool isEditCorrectionError(const ErrorType errorType) { return (errorType & EDIT_CORRECTION) != 0; } diff --git a/native/jni/src/suggest/core/result/suggestions_output_utils.cpp b/native/jni/src/suggest/core/result/suggestions_output_utils.cpp index 74db95953..1aff72952 100644 --- a/native/jni/src/suggest/core/result/suggestions_output_utils.cpp +++ b/native/jni/src/suggest/core/result/suggestions_output_utils.cpp @@ -144,11 +144,16 @@ const int SuggestionsOutputUtils::MIN_LEN_FOR_MULTI_WORD_AUTOCORRECT = 16; const bool isExactMatchWithIntentionalOmission = ErrorTypeUtils::isExactMatchWithIntentionalOmission( terminalDicNode->getContainedErrorTypes()); + // TODO: Decide whether the word should be auto-corrected or not here. + const bool isAppropriateForAutoCorrection = !ErrorTypeUtils::isMissingExplicitAccent( + terminalDicNode->getContainedErrorTypes()); const int outputTypeFlags = (wordAttributes.isPossiblyOffensive() ? Dictionary::KIND_FLAG_POSSIBLY_OFFENSIVE : 0) | ((isExactMatch && boostExactMatches) ? Dictionary::KIND_FLAG_EXACT_MATCH : 0) | (isExactMatchWithIntentionalOmission ? - Dictionary::KIND_FLAG_EXACT_MATCH_WITH_INTENTIONAL_OMISSION : 0); + Dictionary::KIND_FLAG_EXACT_MATCH_WITH_INTENTIONAL_OMISSION : 0) + | (isAppropriateForAutoCorrection ? + Dictionary::KIND_FLAG_APPROPRIATE_FOR_AUTOCORRECTION : 0); // Entries that are blacklisted or do not represent a word should not be output. const bool isValidWord = !(wordAttributes.isBlacklisted() || wordAttributes.isNotAWord()); diff --git a/native/jni/src/suggest/policyimpl/typing/typing_weighting.cpp b/native/jni/src/suggest/policyimpl/typing/typing_weighting.cpp index db7a39efb..a0e54115d 100644 --- a/native/jni/src/suggest/policyimpl/typing/typing_weighting.cpp +++ b/native/jni/src/suggest/policyimpl/typing/typing_weighting.cpp @@ -17,6 +17,7 @@ #include "suggest/policyimpl/typing/typing_weighting.h" #include "suggest/core/dicnode/dic_node.h" +#include "suggest/core/layout/proximity_info.h" #include "suggest/policyimpl/typing/scoring_params.h" namespace latinime { @@ -39,6 +40,8 @@ ErrorTypeUtils::ErrorType TypingWeighting::getErrorType(const CorrectionType cor const int primaryCodePoint = pInfoState->getPrimaryCodePointAt( dicNode->getInputIndex(0)); const int nodeCodePoint = dicNode->getNodeCodePoint(); + const int keyIndex = traverseSession->getProximityInfo()->getKeyIndexOf( + primaryCodePoint); // TODO: Check whether the input code point is on the keyboard. if (primaryCodePoint == nodeCodePoint) { // Node code point is same as original code point on the keyboard. @@ -53,6 +56,9 @@ ErrorTypeUtils::ErrorType TypingWeighting::getErrorType(const CorrectionType cor } else if (CharUtils::toBaseCodePoint(primaryCodePoint) == CharUtils::toBaseCodePoint(nodeCodePoint)) { // Base code points are the same but the code point is intentionally input. + if (keyIndex == NOT_AN_INDEX) { + return ErrorTypeUtils::MATCH_WITH_MISSING_EXPLICIT_ACCENT; + } return ErrorTypeUtils::MATCH_WITH_WRONG_ACCENT; } else if (CharUtils::toLowerCase(primaryCodePoint) == CharUtils::toBaseLowerCase(nodeCodePoint)) { @@ -61,6 +67,10 @@ ErrorTypeUtils::ErrorType TypingWeighting::getErrorType(const CorrectionType cor return ErrorTypeUtils::MATCH_WITH_MISSING_ACCENT | ErrorTypeUtils::MATCH_WITH_WRONG_CASE; } else { + if (keyIndex == NOT_AN_INDEX) { + return ErrorTypeUtils::MATCH_WITH_MISSING_EXPLICIT_ACCENT + | ErrorTypeUtils::MATCH_WITH_WRONG_CASE; + } // Base code points are the same and the cases are different. return ErrorTypeUtils::MATCH_WITH_WRONG_ACCENT | ErrorTypeUtils::MATCH_WITH_WRONG_CASE;