Merge "Fix wrong misspelling reports of fully capitalized words"
commit
b4a9a6deba
|
@ -438,15 +438,23 @@ public final class AndroidSpellCheckerService extends SpellCheckerService
|
|||
if (!Character.isUpperCase(text.codePointAt(0))) return CAPITALIZE_NONE;
|
||||
final int len = text.length();
|
||||
int capsCount = 1;
|
||||
int letterCount = 1;
|
||||
for (int i = 1; i < len; i = text.offsetByCodePoints(i, 1)) {
|
||||
if (1 != capsCount && i != capsCount) break;
|
||||
if (Character.isUpperCase(text.codePointAt(i))) ++capsCount;
|
||||
if (1 != capsCount && letterCount != capsCount) break;
|
||||
final int codePoint = text.codePointAt(i);
|
||||
if (Character.isUpperCase(codePoint)) {
|
||||
++capsCount;
|
||||
++letterCount;
|
||||
} else if (Character.isLetter(codePoint)) {
|
||||
// We need to discount non-letters since they may not be upper-case, but may
|
||||
// still be part of a word (e.g. single quote or dash, as in "IT'S" or "FULL-TIME")
|
||||
++letterCount;
|
||||
}
|
||||
}
|
||||
// We know the first char is upper case. So we want to test if either everything
|
||||
// else is lower case, or if everything else is upper case. If the string is
|
||||
// exactly one char long, then we will arrive here with capsCount 1, and this is
|
||||
// correct, too.
|
||||
// We know the first char is upper case. So we want to test if either every letter other
|
||||
// than the first is lower case, or if they are all upper case. If the string is exactly
|
||||
// one char long, then we will arrive here with letterCount 1, and this is correct, too.
|
||||
if (1 == capsCount) return CAPITALIZE_FIRST;
|
||||
return (len == capsCount ? CAPITALIZE_ALL : CAPITALIZE_NONE);
|
||||
return (letterCount == capsCount ? CAPITALIZE_ALL : CAPITALIZE_NONE);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -28,9 +28,11 @@ import android.view.textservice.TextInfo;
|
|||
|
||||
import com.android.inputmethod.compat.SuggestionsInfoCompatUtils;
|
||||
import com.android.inputmethod.latin.Constants;
|
||||
import com.android.inputmethod.latin.Dictionary;
|
||||
import com.android.inputmethod.latin.LocaleUtils;
|
||||
import com.android.inputmethod.latin.WordComposer;
|
||||
import com.android.inputmethod.latin.StringUtils;
|
||||
import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo;
|
||||
import com.android.inputmethod.latin.WordComposer;
|
||||
import com.android.inputmethod.latin.spellcheck.AndroidSpellCheckerService.SuggestionsGatherer;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
@ -188,6 +190,35 @@ public abstract class AndroidWordLevelSpellCheckerSession extends Session {
|
|||
return (letterCount * 4 < length * 3);
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method to test valid capitalizations of a word.
|
||||
*
|
||||
* If the "text" is lower-case, we test only the exact string.
|
||||
* If the "Text" is capitalized, we test the exact string "Text" and the lower-cased
|
||||
* version of it "text".
|
||||
* If the "TEXT" is fully upper case, we test the exact string "TEXT", the lower-cased
|
||||
* version of it "text" and the capitalized version of it "Text".
|
||||
*/
|
||||
private boolean isInDictForAnyCapitalization(final Dictionary dict, final String text,
|
||||
final int capitalizeType) {
|
||||
// If the word is in there as is, then it's in the dictionary. If not, we'll test lower
|
||||
// case versions, but only if the word is not already all-lower case or mixed case.
|
||||
if (dict.isValidWord(text)) return true;
|
||||
if (AndroidSpellCheckerService.CAPITALIZE_NONE == capitalizeType) return false;
|
||||
|
||||
// If we come here, we have a capitalized word (either First- or All-).
|
||||
// Downcase the word and look it up again. If the word is only capitalized, we
|
||||
// tested all possibilities, so if it's still negative we can return false.
|
||||
final String lowerCaseText = text.toLowerCase(mLocale);
|
||||
if (dict.isValidWord(lowerCaseText)) return true;
|
||||
if (AndroidSpellCheckerService.CAPITALIZE_FIRST == capitalizeType) return false;
|
||||
|
||||
// If the lower case version is not in the dictionary, it's still possible
|
||||
// that we have an all-caps version of a word that needs to be capitalized
|
||||
// according to the dictionary. E.g. "GERMANS" only exists in the dictionary as "Germans".
|
||||
return dict.isValidWord(StringUtils.toTitleCase(lowerCaseText, mLocale));
|
||||
}
|
||||
|
||||
// Note : this must be reentrant
|
||||
/**
|
||||
* Gets a list of suggestions for a specific string. This returns a list of possible
|
||||
|
@ -272,13 +303,7 @@ public abstract class AndroidWordLevelSpellCheckerSession extends Session {
|
|||
suggestionsGatherer.addWord(suggestionStr.toCharArray(), null, 0,
|
||||
suggestionStr.length(), suggestion.mScore);
|
||||
}
|
||||
isInDict = dictInfo.mDictionary.isValidWord(text);
|
||||
if (!isInDict && AndroidSpellCheckerService.CAPITALIZE_NONE != capitalizeType) {
|
||||
// We want to test the word again if it's all caps or first caps only.
|
||||
// If it's fully down, we already tested it, if it's mixed case, we don't
|
||||
// want to test a lowercase version of it.
|
||||
isInDict = dictInfo.mDictionary.isValidWord(text.toLowerCase(mLocale));
|
||||
}
|
||||
isInDict = isInDictForAnyCapitalization(dictInfo.mDictionary, text, capitalizeType);
|
||||
} finally {
|
||||
if (null != dictInfo) {
|
||||
if (!mDictionaryPool.offer(dictInfo)) {
|
||||
|
|
Loading…
Reference in New Issue