aboutsummaryrefslogtreecommitdiffstats
path: root/java/src/com/android/inputmethod/latin/spellcheck
diff options
context:
space:
mode:
Diffstat (limited to 'java/src/com/android/inputmethod/latin/spellcheck')
-rw-r--r--java/src/com/android/inputmethod/latin/spellcheck/AndroidSpellCheckerService.java8
-rw-r--r--java/src/com/android/inputmethod/latin/spellcheck/AndroidWordLevelSpellCheckerSession.java10
-rw-r--r--java/src/com/android/inputmethod/latin/spellcheck/SpellCheckerProximityInfo.java117
3 files changed, 62 insertions, 73 deletions
diff --git a/java/src/com/android/inputmethod/latin/spellcheck/AndroidSpellCheckerService.java b/java/src/com/android/inputmethod/latin/spellcheck/AndroidSpellCheckerService.java
index 8d3b062ff..2d0a89bb3 100644
--- a/java/src/com/android/inputmethod/latin/spellcheck/AndroidSpellCheckerService.java
+++ b/java/src/com/android/inputmethod/latin/spellcheck/AndroidSpellCheckerService.java
@@ -330,7 +330,7 @@ public final class AndroidSpellCheckerService extends SpellCheckerService
} else if (StringUtils.CAPITALIZE_FIRST == capitalizeType) {
for (int i = 0; i < mSuggestions.size(); ++i) {
// Likewise
- mSuggestions.set(i, StringUtils.toTitleCase(
+ mSuggestions.set(i, StringUtils.capitalizeFirstCodePoint(
mSuggestions.get(i).toString(), locale));
}
}
@@ -403,11 +403,7 @@ public final class AndroidSpellCheckerService extends SpellCheckerService
public DictAndProximity createDictAndProximity(final Locale locale) {
final int script = getScriptFromLocale(locale);
- final ProximityInfo proximityInfo = ProximityInfo.createSpellCheckerProximityInfo(
- SpellCheckerProximityInfo.getProximityForScript(script),
- SpellCheckerProximityInfo.ROW_SIZE,
- SpellCheckerProximityInfo.PROXIMITY_GRID_WIDTH,
- SpellCheckerProximityInfo.PROXIMITY_GRID_HEIGHT);
+ final ProximityInfo proximityInfo = new SpellCheckerProximityInfo(script);
final DictionaryCollection dictionaryCollection =
DictionaryFactory.createMainDictionaryFromManager(this, locale,
true /* useFullEditDistance */);
diff --git a/java/src/com/android/inputmethod/latin/spellcheck/AndroidWordLevelSpellCheckerSession.java b/java/src/com/android/inputmethod/latin/spellcheck/AndroidWordLevelSpellCheckerSession.java
index b15063235..da8657201 100644
--- a/java/src/com/android/inputmethod/latin/spellcheck/AndroidWordLevelSpellCheckerSession.java
+++ b/java/src/com/android/inputmethod/latin/spellcheck/AndroidWordLevelSpellCheckerSession.java
@@ -189,10 +189,12 @@ public abstract class AndroidWordLevelSpellCheckerSession extends Session {
int letterCount = 0;
for (int i = 0; i < length; i = text.offsetByCodePoints(i, 1)) {
final int codePoint = text.codePointAt(i);
- // Any word containing a '@' is probably an e-mail address
- // Any word containing a '/' is probably either an ad-hoc combination of two
+ // Any word containing a COMMERCIAL_AT is probably an e-mail address
+ // Any word containing a SLASH is probably either an ad-hoc combination of two
// words or a URI - in either case we don't want to spell check that
- if ('@' == codePoint || '/' == codePoint) return true;
+ if (Constants.CODE_COMMERCIAL_AT == codePoint || Constants.CODE_SLASH == codePoint) {
+ return true;
+ }
if (isLetterCheckableByLanguage(codePoint, script)) ++letterCount;
}
// Guestimate heuristic: perform spell checking if at least 3/4 of the characters
@@ -226,7 +228,7 @@ public abstract class AndroidWordLevelSpellCheckerSession extends Session {
// 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));
+ return dict.isValidWord(StringUtils.capitalizeFirstAndDowncaseRest(lowerCaseText, mLocale));
}
// Note : this must be reentrant
diff --git a/java/src/com/android/inputmethod/latin/spellcheck/SpellCheckerProximityInfo.java b/java/src/com/android/inputmethod/latin/spellcheck/SpellCheckerProximityInfo.java
index 49dca21e6..0c480eaba 100644
--- a/java/src/com/android/inputmethod/latin/spellcheck/SpellCheckerProximityInfo.java
+++ b/java/src/com/android/inputmethod/latin/spellcheck/SpellCheckerProximityInfo.java
@@ -16,53 +16,40 @@
package com.android.inputmethod.latin.spellcheck;
-import com.android.inputmethod.annotations.UsedForTesting;
+import android.util.SparseIntArray;
+
import com.android.inputmethod.keyboard.ProximityInfo;
-import com.android.inputmethod.latin.CollectionUtils;
import com.android.inputmethod.latin.Constants;
-import java.util.TreeMap;
+public final class SpellCheckerProximityInfo extends ProximityInfo {
+ public SpellCheckerProximityInfo(final int script) {
+ super(getProximityForScript(script), PROXIMITY_GRID_WIDTH, PROXIMITY_GRID_HEIGHT);
+ }
-public final class SpellCheckerProximityInfo {
- @UsedForTesting
- final public static int NUL = Constants.NOT_A_CODE;
+ private static final int NUL = Constants.NOT_A_CODE;
// This must be the same as MAX_PROXIMITY_CHARS_SIZE else it will not work inside
// native code - this value is passed at creation of the binary object and reused
// as the size of the passed array afterwards so they can't be different.
- final public static int ROW_SIZE = ProximityInfo.MAX_PROXIMITY_CHARS_SIZE;
+ private static final int ROW_SIZE = ProximityInfo.MAX_PROXIMITY_CHARS_SIZE;
// The number of keys in a row of the grid used by the spell checker.
- final public static int PROXIMITY_GRID_WIDTH = 11;
+ private static final int PROXIMITY_GRID_WIDTH = 11;
// The number of rows in the grid used by the spell checker.
- final public static int PROXIMITY_GRID_HEIGHT = 3;
+ private static final int PROXIMITY_GRID_HEIGHT = 3;
- final private static int NOT_AN_INDEX = -1;
- final public static int NOT_A_COORDINATE_PAIR = -1;
+ private static final int NOT_AN_INDEX = -1;
+ public static final int NOT_A_COORDINATE_PAIR = -1;
// Helper methods
- final protected static void buildProximityIndices(final int[] proximity,
- final TreeMap<Integer, Integer> indices) {
- for (int i = 0; i < proximity.length; i += ROW_SIZE) {
- if (NUL != proximity[i]) indices.put(proximity[i], i / ROW_SIZE);
+ static void buildProximityIndices(final int[] proximity, final int rowSize,
+ final SparseIntArray indices) {
+ for (int i = 0; i < proximity.length; i += rowSize) {
+ if (NUL != proximity[i]) indices.put(proximity[i], i / rowSize);
}
}
- final protected static int computeIndex(final int characterCode,
- final TreeMap<Integer, Integer> indices) {
- final Integer result = indices.get(characterCode);
- if (null == result) return NOT_AN_INDEX;
- return result;
- }
private static final class Latin {
- // This is a map from the code point to the index in the PROXIMITY array.
- // At the time the native code to read the binary dictionary needs the proximity info be
- // passed as a flat array spaced by MAX_PROXIMITY_CHARS_SIZE columns, one for each input
- // character.
- // Since we need to build such an array, we want to be able to search in our big proximity
- // data quickly by character, and a map is probably the best way to do this.
- final private static TreeMap<Integer, Integer> INDICES = CollectionUtils.newTreeMap();
-
// The proximity here is the union of
// - the proximity for a QWERTY keyboard.
// - the proximity for an AZERTY keyboard.
@@ -79,7 +66,7 @@ public final class SpellCheckerProximityInfo {
a s d f g h j k l
z x c v b n m
*/
- final static int[] PROXIMITY = {
+ static final int[] PROXIMITY = {
// Proximity for row 1. This must have exactly ROW_SIZE entries for each letter,
// and exactly PROXIMITY_GRID_WIDTH letters for a row. Pad with NUL's.
// The number of rows must be exactly PROXIMITY_GRID_HEIGHT.
@@ -121,16 +108,21 @@ public final class SpellCheckerProximityInfo {
NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL,
NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL,
};
+
+ // This is a mapping array from the code point to the index in the PROXIMITY array.
+ // When we check the spelling of a word, we need to pass (x,y) coordinates to the native
+ // code for each letter of the word. These are most easily computed from the index in the
+ // PROXIMITY array. Since we'll need to do that very often, the index lookup from the code
+ // point needs to be as fast as possible, and a map is probably the best way to do this.
+ // To avoid unnecessary boxing conversion to Integer, here we use SparseIntArray.
+ static final SparseIntArray INDICES = new SparseIntArray(PROXIMITY.length / ROW_SIZE);
+
static {
- buildProximityIndices(PROXIMITY, INDICES);
- }
- static int getIndexOf(int characterCode) {
- return computeIndex(characterCode, INDICES);
+ buildProximityIndices(PROXIMITY, ROW_SIZE, INDICES);
}
}
private static final class Cyrillic {
- final private static TreeMap<Integer, Integer> INDICES = CollectionUtils.newTreeMap();
// TODO: The following table is solely based on the keyboard layout. Consult with Russian
// speakers on commonly misspelled words/letters.
/*
@@ -207,7 +199,7 @@ public final class SpellCheckerProximityInfo {
private static final int CY_SOFT_SIGN = '\u044C'; // ь
private static final int CY_BE = '\u0431'; // б
private static final int CY_YU = '\u044E'; // ю
- final static int[] PROXIMITY = {
+ static final int[] PROXIMITY = {
// Proximity for row 1. This must have exactly ROW_SIZE entries for each letter,
// and exactly PROXIMITY_GRID_WIDTH letters for a row. Pad with NUL's.
// The number of rows must be exactly PROXIMITY_GRID_HEIGHT.
@@ -280,16 +272,15 @@ public final class SpellCheckerProximityInfo {
NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL,
NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL,
};
+
+ static final SparseIntArray INDICES = new SparseIntArray(PROXIMITY.length / ROW_SIZE);
+
static {
- buildProximityIndices(PROXIMITY, INDICES);
- }
- static int getIndexOf(int characterCode) {
- return computeIndex(characterCode, INDICES);
+ buildProximityIndices(PROXIMITY, ROW_SIZE, INDICES);
}
}
private static final class Greek {
- final private static TreeMap<Integer, Integer> INDICES = CollectionUtils.newTreeMap();
// TODO: The following table is solely based on the keyboard layout. Consult with Greek
// speakers on commonly misspelled words/letters.
/*
@@ -354,7 +345,7 @@ public final class SpellCheckerProximityInfo {
private static final int GR_BETA = '\u03B2'; // β
private static final int GR_NU = '\u03BD'; // ν
private static final int GR_MU = '\u03BC'; // μ
- final static int[] PROXIMITY = {
+ static final int[] PROXIMITY = {
// Proximity for row 1. This must have exactly ROW_SIZE entries for each letter,
// and exactly PROXIMITY_GRID_WIDTH letters for a row. Pad with NUL's.
// The number of rows must be exactly PROXIMITY_GRID_HEIGHT.
@@ -419,37 +410,37 @@ public final class SpellCheckerProximityInfo {
NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL,
NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL,
};
+
+ static final SparseIntArray INDICES = new SparseIntArray(PROXIMITY.length / ROW_SIZE);
+
static {
- buildProximityIndices(PROXIMITY, INDICES);
- }
- static int getIndexOf(int characterCode) {
- return computeIndex(characterCode, INDICES);
+ buildProximityIndices(PROXIMITY, ROW_SIZE, INDICES);
}
}
- public static int[] getProximityForScript(final int script) {
+ private static int[] getProximityForScript(final int script) {
switch (script) {
- case AndroidSpellCheckerService.SCRIPT_LATIN:
- return Latin.PROXIMITY;
- case AndroidSpellCheckerService.SCRIPT_CYRILLIC:
- return Cyrillic.PROXIMITY;
- case AndroidSpellCheckerService.SCRIPT_GREEK:
- return Greek.PROXIMITY;
- default:
- throw new RuntimeException("Wrong script supplied: " + script);
+ case AndroidSpellCheckerService.SCRIPT_LATIN:
+ return Latin.PROXIMITY;
+ case AndroidSpellCheckerService.SCRIPT_CYRILLIC:
+ return Cyrillic.PROXIMITY;
+ case AndroidSpellCheckerService.SCRIPT_GREEK:
+ return Greek.PROXIMITY;
+ default:
+ throw new RuntimeException("Wrong script supplied: " + script);
}
}
private static int getIndexOfCodeForScript(final int codePoint, final int script) {
switch (script) {
- case AndroidSpellCheckerService.SCRIPT_LATIN:
- return Latin.getIndexOf(codePoint);
- case AndroidSpellCheckerService.SCRIPT_CYRILLIC:
- return Cyrillic.getIndexOf(codePoint);
- case AndroidSpellCheckerService.SCRIPT_GREEK:
- return Greek.getIndexOf(codePoint);
- default:
- throw new RuntimeException("Wrong script supplied: " + script);
+ case AndroidSpellCheckerService.SCRIPT_LATIN:
+ return Latin.INDICES.get(codePoint, NOT_AN_INDEX);
+ case AndroidSpellCheckerService.SCRIPT_CYRILLIC:
+ return Cyrillic.INDICES.get(codePoint, NOT_AN_INDEX);
+ case AndroidSpellCheckerService.SCRIPT_GREEK:
+ return Greek.INDICES.get(codePoint, NOT_AN_INDEX);
+ default:
+ throw new RuntimeException("Wrong script supplied: " + script);
}
}