aboutsummaryrefslogtreecommitdiffstats
path: root/java/src
diff options
context:
space:
mode:
Diffstat (limited to 'java/src')
-rw-r--r--java/src/com/android/inputmethod/keyboard/Key.java6
-rw-r--r--java/src/com/android/inputmethod/keyboard/Keyboard.java21
-rw-r--r--java/src/com/android/inputmethod/keyboard/KeyboardId.java56
-rw-r--r--java/src/com/android/inputmethod/keyboard/LatinKeyboardView.java113
-rw-r--r--java/src/com/android/inputmethod/keyboard/ProximityInfo.java8
-rw-r--r--java/src/com/android/inputmethod/latin/BinaryDictionary.java11
-rw-r--r--java/src/com/android/inputmethod/latin/LatinIME.java2
-rw-r--r--java/src/com/android/inputmethod/latin/WordComposer.java49
-rw-r--r--java/src/com/android/inputmethod/latin/makedict/FusionDictionary.java13
-rw-r--r--java/src/com/android/inputmethod/latin/makedict/Word.java23
-rw-r--r--java/src/com/android/inputmethod/latin/spellcheck/AndroidSpellCheckerService.java6
-rw-r--r--java/src/com/android/inputmethod/latin/spellcheck/SpellCheckerProximityInfo.java44
12 files changed, 194 insertions, 158 deletions
diff --git a/java/src/com/android/inputmethod/keyboard/Key.java b/java/src/com/android/inputmethod/keyboard/Key.java
index b09a27540..0a2b010b6 100644
--- a/java/src/com/android/inputmethod/keyboard/Key.java
+++ b/java/src/com/android/inputmethod/keyboard/Key.java
@@ -180,7 +180,7 @@ public class Key {
mY = y;
mHitBox.set(x, y, x + width + 1, y + height);
- mHashCode = hashCode(this);
+ mHashCode = computeHashCode(this);
}
/**
@@ -334,7 +334,7 @@ public class Key {
mAltCode = adjustCaseOfCodeForKeyboardId(style.getInt(keyAttr,
R.styleable.Keyboard_Key_altCode, Keyboard.CODE_UNSPECIFIED), preserveCase,
params.mId);
- mHashCode = hashCode(this);
+ mHashCode = computeHashCode(this);
keyAttr.recycle();
@@ -366,7 +366,7 @@ public class Key {
}
}
- private static int hashCode(Key key) {
+ private static int computeHashCode(Key key) {
return Arrays.hashCode(new Object[] {
key.mX,
key.mY,
diff --git a/java/src/com/android/inputmethod/keyboard/Keyboard.java b/java/src/com/android/inputmethod/keyboard/Keyboard.java
index 2b1cc43cd..07b9c1e8c 100644
--- a/java/src/com/android/inputmethod/keyboard/Keyboard.java
+++ b/java/src/com/android/inputmethod/keyboard/Keyboard.java
@@ -31,6 +31,7 @@ import com.android.inputmethod.keyboard.internal.KeyStyles;
import com.android.inputmethod.keyboard.internal.KeyboardIconsSet;
import com.android.inputmethod.latin.LatinImeLogger;
import com.android.inputmethod.latin.R;
+import com.android.inputmethod.latin.Utils;
import com.android.inputmethod.latin.XmlParseUtils;
import org.xmlpull.v1.XmlPullParser;
@@ -715,22 +716,30 @@ public class Keyboard {
R.styleable.Keyboard_Key);
try {
final int displayHeight = mDisplayMetrics.heightPixels;
- final int keyboardHeight = (int)keyboardAttr.getDimension(
- R.styleable.Keyboard_keyboardHeight, displayHeight / 2);
- final int maxKeyboardHeight = (int)getDimensionOrFraction(keyboardAttr,
+ final String keyboardHeightString = Utils.getDeviceOverrideValue(
+ mResources, R.array.keyboard_heights, null);
+ final float keyboardHeight;
+ if (keyboardHeightString != null) {
+ keyboardHeight = Float.parseFloat(keyboardHeightString)
+ * mDisplayMetrics.density;
+ } else {
+ keyboardHeight = keyboardAttr.getDimension(
+ R.styleable.Keyboard_keyboardHeight, displayHeight / 2);
+ }
+ final float maxKeyboardHeight = getDimensionOrFraction(keyboardAttr,
R.styleable.Keyboard_maxKeyboardHeight, displayHeight, displayHeight / 2);
- int minKeyboardHeight = (int)getDimensionOrFraction(keyboardAttr,
+ float minKeyboardHeight = getDimensionOrFraction(keyboardAttr,
R.styleable.Keyboard_minKeyboardHeight, displayHeight, displayHeight / 2);
if (minKeyboardHeight < 0) {
// Specified fraction was negative, so it should be calculated against display
// width.
- minKeyboardHeight = -(int)getDimensionOrFraction(keyboardAttr,
+ minKeyboardHeight = -getDimensionOrFraction(keyboardAttr,
R.styleable.Keyboard_minKeyboardHeight, displayWidth, displayWidth / 2);
}
final Params params = mParams;
// Keyboard height will not exceed maxKeyboardHeight and will not be less than
// minKeyboardHeight.
- params.mOccupiedHeight = Math.max(
+ params.mOccupiedHeight = (int)Math.max(
Math.min(keyboardHeight, maxKeyboardHeight), minKeyboardHeight);
params.mOccupiedWidth = params.mId.mWidth;
params.mTopPadding = (int)getDimensionOrFraction(keyboardAttr,
diff --git a/java/src/com/android/inputmethod/keyboard/KeyboardId.java b/java/src/com/android/inputmethod/keyboard/KeyboardId.java
index 6703b9301..3b2b11e4e 100644
--- a/java/src/com/android/inputmethod/keyboard/KeyboardId.java
+++ b/java/src/com/android/inputmethod/keyboard/KeyboardId.java
@@ -70,23 +70,23 @@ public class KeyboardId {
public KeyboardId(int elementId, Locale locale, int orientation, int width, int mode,
EditorInfo editorInfo, boolean clobberSettingsKey, boolean shortcutKeyEnabled,
boolean hasShortcutKey, boolean languageSwitchKeyEnabled) {
- this.mLocale = locale;
- this.mOrientation = orientation;
- this.mWidth = width;
- this.mMode = mode;
- this.mElementId = elementId;
- this.mEditorInfo = editorInfo;
- this.mClobberSettingsKey = clobberSettingsKey;
- this.mShortcutKeyEnabled = shortcutKeyEnabled;
- this.mHasShortcutKey = hasShortcutKey;
- this.mLanguageSwitchKeyEnabled = languageSwitchKeyEnabled;
- this.mCustomActionLabel = (editorInfo.actionLabel != null)
+ mLocale = locale;
+ mOrientation = orientation;
+ mWidth = width;
+ mMode = mode;
+ mElementId = elementId;
+ mEditorInfo = editorInfo;
+ mClobberSettingsKey = clobberSettingsKey;
+ mShortcutKeyEnabled = shortcutKeyEnabled;
+ mHasShortcutKey = hasShortcutKey;
+ mLanguageSwitchKeyEnabled = languageSwitchKeyEnabled;
+ mCustomActionLabel = (editorInfo.actionLabel != null)
? editorInfo.actionLabel.toString() : null;
- this.mHashCode = hashCode(this);
+ mHashCode = computeHashCode(this);
}
- private static int hashCode(KeyboardId id) {
+ private static int computeHashCode(KeyboardId id) {
return Arrays.hashCode(new Object[] {
id.mOrientation,
id.mElementId,
@@ -109,21 +109,21 @@ public class KeyboardId {
private boolean equals(KeyboardId other) {
if (other == this)
return true;
- return other.mOrientation == this.mOrientation
- && other.mElementId == this.mElementId
- && other.mMode == this.mMode
- && other.mWidth == this.mWidth
- && other.passwordInput() == this.passwordInput()
- && other.mClobberSettingsKey == this.mClobberSettingsKey
- && other.mShortcutKeyEnabled == this.mShortcutKeyEnabled
- && other.mHasShortcutKey == this.mHasShortcutKey
- && other.mLanguageSwitchKeyEnabled == this.mLanguageSwitchKeyEnabled
- && other.isMultiLine() == this.isMultiLine()
- && other.imeAction() == this.imeAction()
- && TextUtils.equals(other.mCustomActionLabel, this.mCustomActionLabel)
- && other.navigateNext() == this.navigateNext()
- && other.navigatePrevious() == this.navigatePrevious()
- && other.mLocale.equals(this.mLocale);
+ return other.mOrientation == mOrientation
+ && other.mElementId == mElementId
+ && other.mMode == mMode
+ && other.mWidth == mWidth
+ && other.passwordInput() == passwordInput()
+ && other.mClobberSettingsKey == mClobberSettingsKey
+ && other.mShortcutKeyEnabled == mShortcutKeyEnabled
+ && other.mHasShortcutKey == mHasShortcutKey
+ && other.mLanguageSwitchKeyEnabled == mLanguageSwitchKeyEnabled
+ && other.isMultiLine() == isMultiLine()
+ && other.imeAction() == imeAction()
+ && TextUtils.equals(other.mCustomActionLabel, mCustomActionLabel)
+ && other.navigateNext() == navigateNext()
+ && other.navigatePrevious() == navigatePrevious()
+ && other.mLocale.equals(mLocale);
}
public boolean isAlphabetKeyboard() {
diff --git a/java/src/com/android/inputmethod/keyboard/LatinKeyboardView.java b/java/src/com/android/inputmethod/keyboard/LatinKeyboardView.java
index dca15decd..b66d1661d 100644
--- a/java/src/com/android/inputmethod/keyboard/LatinKeyboardView.java
+++ b/java/src/com/android/inputmethod/keyboard/LatinKeyboardView.java
@@ -16,11 +16,8 @@
package com.android.inputmethod.keyboard;
-import android.animation.Animator;
import android.animation.AnimatorInflater;
-import android.animation.AnimatorListenerAdapter;
-import android.animation.ValueAnimator;
-import android.animation.ValueAnimator.AnimatorUpdateListener;
+import android.animation.ObjectAnimator;
import android.content.Context;
import android.content.pm.PackageManager;
import android.content.res.TypedArray;
@@ -76,12 +73,12 @@ public class LatinKeyboardView extends KeyboardView implements PointerTracker.Ke
private Key mSpaceKey;
private Drawable mSpaceIcon;
// Stuff to draw language name on spacebar.
- private ValueAnimator mLanguageOnSpacebarFadeoutAnimator;
- private int mFinalAlphaOfLanguageOnSpacebar;
+ private final int mLanguageOnSpacebarFinalAlpha;
+ private ObjectAnimator mLanguageOnSpacebarFadeoutAnimator;
private static final int ALPHA_OPAQUE = 255;
private boolean mNeedsToDisplayLanguage;
private Locale mSpacebarLocale;
- private int mSpacebarTextAlpha = ALPHA_OPAQUE;
+ private int mLanguageOnSpacebarAnimAlpha = ALPHA_OPAQUE;
private final float mSpacebarTextRatio;
private float mSpacebarTextSize;
private final int mSpacebarTextColor;
@@ -96,8 +93,8 @@ public class LatinKeyboardView extends KeyboardView implements PointerTracker.Ke
private static final int SPACE_LED_LENGTH_PERCENT = 80;
// Stuff to draw altCodeWhileTyping keys.
- private ValueAnimator mAltCodeKeyWhileTypingFadeoutAnimator;
- private ValueAnimator mAltCodeKeyWhileTypingFadeinAnimator;
+ private ObjectAnimator mAltCodeKeyWhileTypingFadeoutAnimator;
+ private ObjectAnimator mAltCodeKeyWhileTypingFadeinAnimator;
private int mAltCodeKeyWhileTypingAnimAlpha = ALPHA_OPAQUE;
// More keys keyboard
@@ -227,8 +224,8 @@ public class LatinKeyboardView extends KeyboardView implements PointerTracker.Ke
removeMessages(MSG_LONGPRESS_KEY);
}
- private static void cancelAndStartAnimators(ValueAnimator animatorToCancel,
- ValueAnimator animatorToStart) {
+ public static void cancelAndStartAnimators(ObjectAnimator animatorToCancel,
+ ObjectAnimator animatorToStart) {
if (animatorToCancel != null && animatorToCancel.isStarted()) {
animatorToCancel.cancel();
}
@@ -362,6 +359,8 @@ public class LatinKeyboardView extends KeyboardView implements PointerTracker.Ke
mSpacebarTextColor = a.getColor(R.styleable.LatinKeyboardView_spacebarTextColor, 0);
mSpacebarTextShadowColor = a.getColor(
R.styleable.LatinKeyboardView_spacebarTextShadowColor, 0);
+ mLanguageOnSpacebarFinalAlpha = a.getInt(
+ R.styleable.LatinKeyboardView_languageOnSpacebarFinalAlpha, ALPHA_OPAQUE);
final int languageOnSpacebarFadeoutAnimatorResId = a.getResourceId(
R.styleable.LatinKeyboardView_languageOnSpacebarFadeoutAnimator, 0);
final int altCodeKeyWhileTypingFadeoutAnimatorResId = a.getResourceId(
@@ -383,55 +382,41 @@ public class LatinKeyboardView extends KeyboardView implements PointerTracker.Ke
PointerTracker.setParameters(mPointerTrackerParams);
- final ValueAnimator animator = loadValueAnimator(languageOnSpacebarFadeoutAnimatorResId);
+ mLanguageOnSpacebarFadeoutAnimator = loadObjectAnimator(
+ languageOnSpacebarFadeoutAnimatorResId, this);
+ mAltCodeKeyWhileTypingFadeoutAnimator = loadObjectAnimator(
+ altCodeKeyWhileTypingFadeoutAnimatorResId, this);
+ mAltCodeKeyWhileTypingFadeinAnimator = loadObjectAnimator(
+ altCodeKeyWhileTypingFadeinAnimatorResId, this);
+ }
+
+ private ObjectAnimator loadObjectAnimator(int resId, Object target) {
+ if (resId == 0) return null;
+ final ObjectAnimator animator = (ObjectAnimator)AnimatorInflater.loadAnimator(
+ getContext(), resId);
if (animator != null) {
- animator.addUpdateListener(new AnimatorUpdateListener() {
- @Override
- public void onAnimationUpdate(ValueAnimator animation) {
- mSpacebarTextAlpha = (Integer)animation.getAnimatedValue();
- invalidateKey(mSpaceKey);
- }
- });
- animator.addListener(new AnimatorListenerAdapter() {
- @Override
- public void onAnimationEnd(Animator a) {
- final ValueAnimator valueAnimator = (ValueAnimator)a;
- mFinalAlphaOfLanguageOnSpacebar = (Integer)valueAnimator.getAnimatedValue();
- }
- });
- // In order to get the final value of animator.
- animator.end();
- }
- mLanguageOnSpacebarFadeoutAnimator = animator;
-
- final ValueAnimator fadeout = loadValueAnimator(altCodeKeyWhileTypingFadeoutAnimatorResId);
- if (fadeout != null) {
- fadeout.addUpdateListener(new AnimatorUpdateListener() {
- @Override
- public void onAnimationUpdate(ValueAnimator animation) {
- mAltCodeKeyWhileTypingAnimAlpha = (Integer)animation.getAnimatedValue();
- updateAltCodeKeyWhileTyping();
- }
- });
+ animator.setTarget(target);
}
- mAltCodeKeyWhileTypingFadeoutAnimator = fadeout;
+ return animator;
+ }
- final ValueAnimator fadein = loadValueAnimator(altCodeKeyWhileTypingFadeinAnimatorResId);
- if (fadein != null) {
- fadein.addUpdateListener(new AnimatorUpdateListener() {
- @Override
- public void onAnimationUpdate(ValueAnimator animation) {
- mAltCodeKeyWhileTypingAnimAlpha = (Integer)animation.getAnimatedValue();
- updateAltCodeKeyWhileTyping();
- }
- });
- }
- mAltCodeKeyWhileTypingFadeinAnimator = fadein;
+ // Getter/setter methods for {@link ObjectAnimator}.
+ public int getLanguageOnSpacebarAnimAlpha() {
+ return mLanguageOnSpacebarAnimAlpha;
}
- private ValueAnimator loadValueAnimator(int resId) {
- if (resId == 0) return null;
- return (ValueAnimator)AnimatorInflater.loadAnimator(getContext(), resId);
+ public void setLanguageOnSpacebarAnimAlpha(int alpha) {
+ mLanguageOnSpacebarAnimAlpha = alpha;
+ invalidateKey(mSpaceKey);
+ }
+
+ public int getAltCodeKeyWhileTypingAnimAlpha() {
+ return mAltCodeKeyWhileTypingAnimAlpha;
+ }
+
+ public void setAltCodeKeyWhileTypingAnimAlpha(int alpha) {
+ mAltCodeKeyWhileTypingAnimAlpha = alpha;
+ updateAltCodeKeyWhileTyping();
}
public void setKeyboardActionListener(KeyboardActionListener listener) {
@@ -836,19 +821,21 @@ public class LatinKeyboardView extends KeyboardView implements PointerTracker.Ke
public void startDisplayLanguageOnSpacebar(boolean subtypeChanged,
boolean needsToDisplayLanguage) {
- final ValueAnimator animator = mLanguageOnSpacebarFadeoutAnimator;
- if (animator != null) {
- animator.cancel();
- }
+ final ObjectAnimator animator = mLanguageOnSpacebarFadeoutAnimator;
mNeedsToDisplayLanguage = needsToDisplayLanguage;
if (animator == null) {
mNeedsToDisplayLanguage = false;
} else {
if (subtypeChanged && needsToDisplayLanguage) {
- mSpacebarTextAlpha = ALPHA_OPAQUE;
+ setLanguageOnSpacebarAnimAlpha(ALPHA_OPAQUE);
+ if (animator.isStarted()) {
+ animator.cancel();
+ }
animator.start();
} else {
- mSpacebarTextAlpha = mFinalAlphaOfLanguageOnSpacebar;
+ if (!animator.isStarted()) {
+ mLanguageOnSpacebarAnimAlpha = mLanguageOnSpacebarFinalAlpha;
+ }
}
}
invalidateKey(mSpaceKey);
@@ -942,10 +929,10 @@ public class LatinKeyboardView extends KeyboardView implements PointerTracker.Ke
final float textHeight = -paint.ascent() + descent;
final float baseline = height / 2 + textHeight / 2;
paint.setColor(mSpacebarTextShadowColor);
- paint.setAlpha(mSpacebarTextAlpha);
+ paint.setAlpha(mLanguageOnSpacebarAnimAlpha);
canvas.drawText(language, width / 2, baseline - descent - 1, paint);
paint.setColor(mSpacebarTextColor);
- paint.setAlpha(mSpacebarTextAlpha);
+ paint.setAlpha(mLanguageOnSpacebarAnimAlpha);
canvas.drawText(language, width / 2, baseline - descent, paint);
}
diff --git a/java/src/com/android/inputmethod/keyboard/ProximityInfo.java b/java/src/com/android/inputmethod/keyboard/ProximityInfo.java
index 442413c0c..5c1808613 100644
--- a/java/src/com/android/inputmethod/keyboard/ProximityInfo.java
+++ b/java/src/com/android/inputmethod/keyboard/ProximityInfo.java
@@ -79,8 +79,12 @@ public class ProximityInfo {
final ProximityInfo spellCheckerProximityInfo = createDummyProximityInfo();
spellCheckerProximityInfo.mNativeProximityInfo =
spellCheckerProximityInfo.setProximityInfoNative("",
- SpellCheckerProximityInfo.ROW_SIZE, 480, 300, 11, 3, (480 / 10), proximity,
- 0, null, null, null, null, null, null, null, null);
+ SpellCheckerProximityInfo.ROW_SIZE,
+ SpellCheckerProximityInfo.PROXIMITY_GRID_WIDTH,
+ SpellCheckerProximityInfo.PROXIMITY_GRID_HEIGHT,
+ SpellCheckerProximityInfo.PROXIMITY_GRID_WIDTH,
+ SpellCheckerProximityInfo.PROXIMITY_GRID_HEIGHT,
+ 1, proximity, 0, null, null, null, null, null, null, null, null);
return spellCheckerProximityInfo;
}
diff --git a/java/src/com/android/inputmethod/latin/BinaryDictionary.java b/java/src/com/android/inputmethod/latin/BinaryDictionary.java
index dfc8c8e9d..a9df1ce12 100644
--- a/java/src/com/android/inputmethod/latin/BinaryDictionary.java
+++ b/java/src/com/android/inputmethod/latin/BinaryDictionary.java
@@ -55,6 +55,8 @@ public class BinaryDictionary extends Dictionary {
public static final Flag FLAG_REQUIRES_GERMAN_UMLAUT_PROCESSING =
new Flag(R.bool.config_require_umlaut_processing, 0x1);
+ public static final Flag FLAG_REQUIRES_FRENCH_LIGATURES_PROCESSING =
+ new Flag(R.bool.config_require_ligatures_processing, 0x4);
// FULL_EDIT_DISTANCE is a flag that forces the dictionary to use full words
// when computing edit distance, instead of the default behavior of stopping
@@ -77,6 +79,7 @@ public class BinaryDictionary extends Dictionary {
// actual value will be read from the configuration/extra value at run time for
// the configuration at dictionary creation time.
FLAG_REQUIRES_GERMAN_UMLAUT_PROCESSING,
+ FLAG_REQUIRES_FRENCH_LIGATURES_PROCESSING,
};
private int mFlags = 0;
@@ -202,9 +205,11 @@ public class BinaryDictionary extends Dictionary {
Arrays.fill(mInputCodes, WordComposer.NOT_A_CODE);
for (int i = 0; i < codesSize; i++) {
- int[] alternatives = codes.getCodesAt(i);
- System.arraycopy(alternatives, 0, mInputCodes, i * MAX_PROXIMITY_CHARS_SIZE,
- Math.min(alternatives.length, MAX_PROXIMITY_CHARS_SIZE));
+ final int[] alternatives = codes.getCodesAt(i);
+ if (alternatives == null || alternatives.length < 1) {
+ continue;
+ }
+ mInputCodes[i] = alternatives[0];
}
Arrays.fill(outputChars, (char) 0);
Arrays.fill(scores, 0);
diff --git a/java/src/com/android/inputmethod/latin/LatinIME.java b/java/src/com/android/inputmethod/latin/LatinIME.java
index 48fb79809..7903820f7 100644
--- a/java/src/com/android/inputmethod/latin/LatinIME.java
+++ b/java/src/com/android/inputmethod/latin/LatinIME.java
@@ -197,7 +197,7 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
private InputMethodManagerCompatWrapper mImm;
private Resources mResources;
private SharedPreferences mPrefs;
- private final KeyboardSwitcher mKeyboardSwitcher;
+ /* package for tests */ final KeyboardSwitcher mKeyboardSwitcher;
private final SubtypeSwitcher mSubtypeSwitcher;
private VoiceProxy mVoiceProxy;
private boolean mShouldSwitchToLastSubtype = true;
diff --git a/java/src/com/android/inputmethod/latin/WordComposer.java b/java/src/com/android/inputmethod/latin/WordComposer.java
index 9f23f174f..cabf68099 100644
--- a/java/src/com/android/inputmethod/latin/WordComposer.java
+++ b/java/src/com/android/inputmethod/latin/WordComposer.java
@@ -20,8 +20,6 @@ import com.android.inputmethod.keyboard.Key;
import com.android.inputmethod.keyboard.KeyDetector;
import com.android.inputmethod.keyboard.Keyboard;
import com.android.inputmethod.keyboard.KeyboardActionListener;
-import com.android.inputmethod.latin.spellcheck.AndroidSpellCheckerService;
-import com.android.inputmethod.latin.spellcheck.SpellCheckerProximityInfo;
import java.util.ArrayList;
import java.util.Arrays;
@@ -127,12 +125,8 @@ public class WordComposer {
final int[] codes;
final int keyX;
final int keyY;
- if (x == KeyboardActionListener.SPELL_CHECKER_COORDINATE
- || y == KeyboardActionListener.SPELL_CHECKER_COORDINATE) {
- // only used for tests in InputLogicTests
- addKeyForSpellChecker(primaryCode, AndroidSpellCheckerService.SCRIPT_LATIN);
- return;
- } else if (x == KeyboardActionListener.SUGGESTION_STRIP_COORDINATE
+ if (null == keyDetector
+ || x == KeyboardActionListener.SUGGESTION_STRIP_COORDINATE
|| y == KeyboardActionListener.SUGGESTION_STRIP_COORDINATE
|| x == KeyboardActionListener.NOT_A_TOUCH_COORDINATE
|| y == KeyboardActionListener.NOT_A_TOUCH_COORDINATE) {
@@ -149,27 +143,6 @@ public class WordComposer {
add(primaryCode, codes, keyX, keyY);
}
- // TODO: remove this function
- public void addKeyForSpellChecker(int primaryCode, int script) {
- final int[] proximities;
- final int proximityIndex =
- SpellCheckerProximityInfo.getIndexOfCodeForScript(primaryCode, script);
- if (-1 == proximityIndex) {
- proximities = new int[] { primaryCode };
- } else {
- // TODO: an initial examination seems to reveal this is actually used
- // read-only. It should be possible to compute the arrays statically once
- // and skip doing a copy each time here.
- proximities = Arrays.copyOfRange(
- SpellCheckerProximityInfo.getProximityForScript(script),
- proximityIndex,
- proximityIndex + SpellCheckerProximityInfo.ROW_SIZE);
- }
- add(primaryCode, proximities,
- KeyboardActionListener.NOT_A_TOUCH_COORDINATE,
- KeyboardActionListener.NOT_A_TOUCH_COORDINATE);
- }
-
/**
* Add a new keystroke, with codes[0] containing the pressed key's unicode and the rest of
* the array containing unicode for adjacent keys, sorted by reducing probability/proximity.
@@ -197,8 +170,7 @@ public class WordComposer {
/**
* Internal method to retrieve reasonable proximity info for a character.
*/
- private void addKeyInfo(final int codePoint, final Keyboard keyboard,
- final KeyDetector keyDetector) {
+ private void addKeyInfo(final int codePoint, final Keyboard keyboard) {
for (final Key key : keyboard.mKeys) {
if (key.mCode == codePoint) {
final int x = key.mX + key.mWidth / 2;
@@ -216,27 +188,16 @@ public class WordComposer {
* Set the currently composing word to the one passed as an argument.
* This will register NOT_A_COORDINATE for X and Ys, and use the passed keyboard for proximity.
*/
- private void setComposingWord(final CharSequence word, final Keyboard keyboard,
- final KeyDetector keyDetector) {
+ public void setComposingWord(final CharSequence word, final Keyboard keyboard) {
reset();
final int length = word.length();
for (int i = 0; i < length; i = Character.offsetByCodePoints(word, i, 1)) {
int codePoint = Character.codePointAt(word, i);
- addKeyInfo(codePoint, keyboard, keyDetector);
+ addKeyInfo(codePoint, keyboard);
}
}
/**
- * Shortcut for the above method, this will create a new KeyDetector for the passed keyboard.
- */
- public void setComposingWord(final CharSequence word, final Keyboard keyboard) {
- final KeyDetector keyDetector = new KeyDetector(0);
- keyDetector.setKeyboard(keyboard, 0, 0);
- keyDetector.setProximityCorrectionEnabled(true);
- setComposingWord(word, keyboard, keyDetector);
- }
-
- /**
* Delete the last keystroke as a result of hitting backspace.
*/
public void deleteLast() {
diff --git a/java/src/com/android/inputmethod/latin/makedict/FusionDictionary.java b/java/src/com/android/inputmethod/latin/makedict/FusionDictionary.java
index 9dc294edf..64fcd7f1a 100644
--- a/java/src/com/android/inputmethod/latin/makedict/FusionDictionary.java
+++ b/java/src/com/android/inputmethod/latin/makedict/FusionDictionary.java
@@ -64,6 +64,19 @@ public class FusionDictionary implements Iterable<Word> {
mWord = word;
mFrequency = frequency;
}
+
+ @Override
+ public int hashCode() {
+ return Arrays.hashCode(new Object[] { mWord, mFrequency });
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (o == this) return true;
+ if (!(o instanceof WeightedString)) return false;
+ WeightedString w = (WeightedString)o;
+ return mWord.equals(w.mWord) && mFrequency == w.mFrequency;
+ }
}
/**
diff --git a/java/src/com/android/inputmethod/latin/makedict/Word.java b/java/src/com/android/inputmethod/latin/makedict/Word.java
index c2c01e1f8..4e0ab1049 100644
--- a/java/src/com/android/inputmethod/latin/makedict/Word.java
+++ b/java/src/com/android/inputmethod/latin/makedict/Word.java
@@ -19,6 +19,7 @@ package com.android.inputmethod.latin.makedict;
import com.android.inputmethod.latin.makedict.FusionDictionary.WeightedString;
import java.util.ArrayList;
+import java.util.Arrays;
/**
* Utility class for a word with a frequency.
@@ -32,6 +33,8 @@ public class Word implements Comparable<Word> {
final ArrayList<WeightedString> mShortcutTargets;
final ArrayList<WeightedString> mBigrams;
+ private int mHashCode = 0;
+
public Word(final String word, final int frequency,
final ArrayList<WeightedString> shortcutTargets,
final ArrayList<WeightedString> bigrams, final boolean isShortcutOnly) {
@@ -42,6 +45,16 @@ public class Word implements Comparable<Word> {
mIsShortcutOnly = isShortcutOnly;
}
+ private static int computeHashCode(Word word) {
+ return Arrays.hashCode(new Object[] {
+ word.mWord,
+ word.mFrequency,
+ word.mIsShortcutOnly,
+ word.mShortcutTargets.hashCode(),
+ word.mBigrams.hashCode()
+ });
+ }
+
/**
* Three-way comparison.
*
@@ -63,10 +76,20 @@ public class Word implements Comparable<Word> {
*/
@Override
public boolean equals(Object o) {
+ if (o == this) return true;
if (!(o instanceof Word)) return false;
Word w = (Word)o;
return mFrequency == w.mFrequency && mWord.equals(w.mWord)
+ && mIsShortcutOnly == w.mIsShortcutOnly
&& mShortcutTargets.equals(w.mShortcutTargets)
&& mBigrams.equals(w.mBigrams);
}
+
+ @Override
+ public int hashCode() {
+ if (mHashCode == 0) {
+ mHashCode = computeHashCode(this);
+ }
+ return mHashCode;
+ }
}
diff --git a/java/src/com/android/inputmethod/latin/spellcheck/AndroidSpellCheckerService.java b/java/src/com/android/inputmethod/latin/spellcheck/AndroidSpellCheckerService.java
index 35a5c0f52..973a448ee 100644
--- a/java/src/com/android/inputmethod/latin/spellcheck/AndroidSpellCheckerService.java
+++ b/java/src/com/android/inputmethod/latin/spellcheck/AndroidSpellCheckerService.java
@@ -570,7 +570,11 @@ public class AndroidSpellCheckerService extends SpellCheckerService
final WordComposer composer = new WordComposer();
final int length = text.length();
for (int i = 0; i < length; i = text.offsetByCodePoints(i, 1)) {
- composer.addKeyForSpellChecker(text.codePointAt(i), mScript);
+ final int codePoint = text.codePointAt(i);
+ // The getXYForCodePointAndScript method returns (Y << 16) + X
+ final int xy = SpellCheckerProximityInfo.getXYForCodePointAndScript(
+ codePoint, mScript);
+ composer.add(codePoint, xy & 0xFFFF, xy >> 16, null);
}
final int capitalizeType = getCapitalizationType(text);
diff --git a/java/src/com/android/inputmethod/latin/spellcheck/SpellCheckerProximityInfo.java b/java/src/com/android/inputmethod/latin/spellcheck/SpellCheckerProximityInfo.java
index db3544987..7627700dd 100644
--- a/java/src/com/android/inputmethod/latin/spellcheck/SpellCheckerProximityInfo.java
+++ b/java/src/com/android/inputmethod/latin/spellcheck/SpellCheckerProximityInfo.java
@@ -30,11 +30,16 @@ public class SpellCheckerProximityInfo {
// 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;
+ // The number of keys in a row of the grid used by the spell checker.
+ final public static 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;
+
// 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);
+ if (NUL != proximity[i]) indices.put(proximity[i], i / ROW_SIZE);
}
}
final protected static int computeIndex(final int characterCode,
@@ -64,6 +69,9 @@ public class SpellCheckerProximityInfo {
// to English, many spelling errors consist of the last vowel of the word being wrong
// because in English vowels tend to merge with each other in pronunciation.
final static 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.
'q', 'w', 's', 'a', 'z', NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL,
'w', 'q', 'a', 's', 'd', 'e', 'x', NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL,
'e', 'w', 's', 'd', 'f', 'r', 'a', 'i', 'o', 'u', NUL, NUL, NUL, NUL, NUL, NUL,
@@ -76,9 +84,10 @@ public class SpellCheckerProximityInfo {
'p', 'o', 'l', 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,
+ // Proximity for row 2. See comment above about size.
'a', 'z', 'x', 's', 'w', 'q', 'e', 'i', 'o', 'u', NUL, NUL, NUL, NUL, NUL, NUL,
's', 'q', 'a', 'z', 'x', 'c', 'd', 'e', 'w', NUL, NUL, NUL, NUL, NUL, NUL, NUL,
- 'd', 'w', 's', 'x', 'c', 'v', 'f', 'r', 'e', 'w', NUL, NUL, NUL, NUL, NUL, NUL,
+ 'd', 'w', 's', 'x', 'c', 'v', 'f', 'r', 'e', NUL, NUL, NUL, NUL, NUL, NUL, NUL,
'f', 'e', 'd', 'c', 'v', 'b', 'g', 't', 'r', NUL, NUL, NUL, NUL, NUL, NUL, NUL,
'g', 'r', 'f', 'v', 'b', 'n', 'h', 'y', 't', NUL, NUL, NUL, NUL, NUL, NUL, NUL,
'h', 't', 'g', 'b', 'n', 'm', 'j', 'u', 'y', NUL, NUL, NUL, NUL, NUL, NUL, NUL,
@@ -88,6 +97,7 @@ public 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,
+ // Proximity for row 3. See comment above about size.
'z', 'a', 's', 'd', 'x', 't', 'g', 'h', 'j', 'u', 'q', 'e', NUL, NUL, NUL, NUL,
'x', 'z', 'a', 's', 'd', 'c', NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL,
'c', 'x', 's', 'd', 'f', 'v', NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL,
@@ -109,9 +119,12 @@ public class SpellCheckerProximityInfo {
private static class Cyrillic {
final private static TreeMap<Integer, Integer> INDICES = new TreeMap<Integer, Integer>();
+ // TODO: The following table is solely based on the keyboard layout. Consult with Russian
+ // speakers on commonly misspelled words/letters.
final static int[] PROXIMITY = {
- // TODO: This table is solely based on the keyboard layout. Consult with Russian
- // speakers on commonly misspelled words/letters.
+ // 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.
'й', 'ц', 'ф', 'ы', 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,
@@ -124,6 +137,7 @@ public class SpellCheckerProximityInfo {
'з', 'щ', 'д', 'ж', 'э', 'х', NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL,
'х', 'з', 'ж', 'э', NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL,
+ // Proximity for row 2. See comment above about size.
'ф', 'й', 'ц', 'ы', 'я', 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,
@@ -136,6 +150,7 @@ public class SpellCheckerProximityInfo {
'ж', 'щ', 'з', 'х', 'д', 'э', 'б', 'ю', NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL,
'э', 'з', 'х', 'ю', NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL,
+ // Proximity for row 3. See comment above about size.
'я', 'ф', 'ы', 'в', 'ч', 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,
@@ -166,14 +181,29 @@ public class SpellCheckerProximityInfo {
throw new RuntimeException("Wrong script supplied: " + script);
}
}
- public static int getIndexOfCodeForScript(final int characterCode, final int script) {
+
+ private static int getIndexOfCodeForScript(final int codePoint, final int script) {
switch (script) {
case AndroidSpellCheckerService.SCRIPT_LATIN:
- return Latin.getIndexOf(characterCode);
+ return Latin.getIndexOf(codePoint);
case AndroidSpellCheckerService.SCRIPT_CYRILLIC:
- return Cyrillic.getIndexOf(characterCode);
+ return Cyrillic.getIndexOf(codePoint);
default:
throw new RuntimeException("Wrong script supplied: " + script);
}
}
+
+ // Returns (Y << 16) + X to avoid creating a temporary object. This is okay because
+ // X and Y are limited to PROXIMITY_GRID_WIDTH resp. PROXIMITY_GRID_HEIGHT which is very
+ // inferior to 1 << 16
+ public static int getXYForCodePointAndScript(final int codePoint, final int script) {
+ final int index = getIndexOfCodeForScript(codePoint, script);
+ final int y = index / PROXIMITY_GRID_WIDTH;
+ final int x = index % PROXIMITY_GRID_WIDTH;
+ if (y > PROXIMITY_GRID_HEIGHT) {
+ // Safety check, should be entirely useless
+ throw new RuntimeException("Wrong y coordinate in spell checker proximity");
+ }
+ return (y << 16) + x;
+ }
}