Loading java/src/com/android/inputmethod/latin/WordComposer.java +50 −70 Original line number Original line Diff line number Diff line Loading @@ -33,45 +33,17 @@ public class WordComposer { public static final int NOT_A_CODE = KeyDetector.NOT_A_CODE; public static final int NOT_A_CODE = KeyDetector.NOT_A_CODE; public static final int NOT_A_COORDINATE = -1; public static final int NOT_A_COORDINATE = -1; // Storage for all the info about the current input. private static class CharacterStore { /** * The list of unicode values for each keystroke (including surrounding keys) */ ArrayList<int[]> mCodes; int[] mXCoordinates; int[] mYCoordinates; StringBuilder mTypedWord; CharSequence mAutoCorrection; CharacterStore() { final int N = BinaryDictionary.MAX_WORD_LENGTH; final int N = BinaryDictionary.MAX_WORD_LENGTH; mCodes = new ArrayList<int[]>(N); mTypedWord = new StringBuilder(N); mXCoordinates = new int[N]; mYCoordinates = new int[N]; mAutoCorrection = null; } CharacterStore(final CharacterStore that) { mCodes = new ArrayList<int[]>(that.mCodes); mTypedWord = new StringBuilder(that.mTypedWord); mXCoordinates = Arrays.copyOf(that.mXCoordinates, that.mXCoordinates.length); mYCoordinates = Arrays.copyOf(that.mYCoordinates, that.mYCoordinates.length); } void reset() { // For better performance than creating a new character store. mCodes.clear(); mTypedWord.setLength(0); mAutoCorrection = null; } } // The currently typing word. May not be null. private ArrayList<int[]> mCodes; private CharacterStore mCurrentWord; private int[] mXCoordinates; private int[] mYCoordinates; private StringBuilder mTypedWord; private CharSequence mAutoCorrection; // Cache these values for performance private int mCapsCount; private int mCapsCount; private boolean mAutoCapitalized; private boolean mAutoCapitalized; // Cache this value for performance private int mTrailingSingleQuotesCount; private int mTrailingSingleQuotesCount; /** /** Loading @@ -80,7 +52,11 @@ public class WordComposer { private boolean mIsFirstCharCapitalized; private boolean mIsFirstCharCapitalized; public WordComposer() { public WordComposer() { mCurrentWord = new CharacterStore(); mCodes = new ArrayList<int[]>(N); mTypedWord = new StringBuilder(N); mXCoordinates = new int[N]; mYCoordinates = new int[N]; mAutoCorrection = null; mTrailingSingleQuotesCount = 0; mTrailingSingleQuotesCount = 0; } } Loading @@ -89,7 +65,10 @@ public class WordComposer { } } public void init(WordComposer source) { public void init(WordComposer source) { mCurrentWord = new CharacterStore(source.mCurrentWord); mCodes = new ArrayList<int[]>(source.mCodes); mTypedWord = new StringBuilder(source.mTypedWord); mXCoordinates = Arrays.copyOf(source.mXCoordinates, source.mXCoordinates.length); mYCoordinates = Arrays.copyOf(source.mYCoordinates, source.mYCoordinates.length); mCapsCount = source.mCapsCount; mCapsCount = source.mCapsCount; mIsFirstCharCapitalized = source.mIsFirstCharCapitalized; mIsFirstCharCapitalized = source.mIsFirstCharCapitalized; mAutoCapitalized = source.mAutoCapitalized; mAutoCapitalized = source.mAutoCapitalized; Loading @@ -100,7 +79,9 @@ public class WordComposer { * Clear out the keys registered so far. * Clear out the keys registered so far. */ */ public void reset() { public void reset() { mCurrentWord.reset(); mCodes.clear(); mTypedWord.setLength(0); mAutoCorrection = null; mCapsCount = 0; mCapsCount = 0; mIsFirstCharCapitalized = false; mIsFirstCharCapitalized = false; mTrailingSingleQuotesCount = 0; mTrailingSingleQuotesCount = 0; Loading @@ -111,7 +92,7 @@ public class WordComposer { * @return the number of keystrokes * @return the number of keystrokes */ */ public final int size() { public final int size() { return mCurrentWord.mTypedWord.length(); return mTypedWord.length(); } } public final boolean isComposingWord() { public final boolean isComposingWord() { Loading @@ -124,15 +105,15 @@ public class WordComposer { * @return the unicode for the pressed and surrounding keys * @return the unicode for the pressed and surrounding keys */ */ public int[] getCodesAt(int index) { public int[] getCodesAt(int index) { return mCurrentWord.mCodes.get(index); return mCodes.get(index); } } public int[] getXCoordinates() { public int[] getXCoordinates() { return mCurrentWord.mXCoordinates; return mXCoordinates; } } public int[] getYCoordinates() { public int[] getYCoordinates() { return mCurrentWord.mYCoordinates; return mYCoordinates; } } private static boolean isFirstCharCapitalized(int index, int codePoint, boolean previous) { private static boolean isFirstCharCapitalized(int index, int codePoint, boolean previous) { Loading @@ -147,12 +128,12 @@ public class WordComposer { */ */ public void add(int primaryCode, int[] codes, int x, int y) { public void add(int primaryCode, int[] codes, int x, int y) { final int newIndex = size(); final int newIndex = size(); mCurrentWord.mTypedWord.append((char) primaryCode); mTypedWord.append((char) primaryCode); correctPrimaryJuxtapos(primaryCode, codes); correctPrimaryJuxtapos(primaryCode, codes); mCurrentWord.mCodes.add(codes); mCodes.add(codes); if (newIndex < BinaryDictionary.MAX_WORD_LENGTH) { if (newIndex < BinaryDictionary.MAX_WORD_LENGTH) { mCurrentWord.mXCoordinates[newIndex] = x; mXCoordinates[newIndex] = x; mCurrentWord.mYCoordinates[newIndex] = y; mYCoordinates[newIndex] = y; } } mIsFirstCharCapitalized = isFirstCharCapitalized( mIsFirstCharCapitalized = isFirstCharCapitalized( newIndex, primaryCode, mIsFirstCharCapitalized); newIndex, primaryCode, mIsFirstCharCapitalized); Loading @@ -162,7 +143,7 @@ public class WordComposer { } else { } else { mTrailingSingleQuotesCount = 0; mTrailingSingleQuotesCount = 0; } } mCurrentWord.mAutoCorrection = null; mAutoCorrection = null; } } /** /** Loading Loading @@ -231,9 +212,9 @@ public class WordComposer { final int size = size(); final int size = size(); if (size > 0) { if (size > 0) { final int lastPos = size - 1; final int lastPos = size - 1; char lastChar = mCurrentWord.mTypedWord.charAt(lastPos); char lastChar = mTypedWord.charAt(lastPos); mCurrentWord.mCodes.remove(lastPos); mCodes.remove(lastPos); mCurrentWord.mTypedWord.deleteCharAt(lastPos); mTypedWord.deleteCharAt(lastPos); if (Character.isUpperCase(lastChar)) mCapsCount--; if (Character.isUpperCase(lastChar)) mCapsCount--; } } if (size() == 0) { if (size() == 0) { Loading @@ -242,12 +223,12 @@ public class WordComposer { if (mTrailingSingleQuotesCount > 0) { if (mTrailingSingleQuotesCount > 0) { --mTrailingSingleQuotesCount; --mTrailingSingleQuotesCount; } else { } else { for (int i = mCurrentWord.mTypedWord.length() - 1; i >= 0; --i) { for (int i = mTypedWord.length() - 1; i >= 0; --i) { if (Keyboard.CODE_SINGLE_QUOTE != mCurrentWord.mTypedWord.codePointAt(i)) break; if (Keyboard.CODE_SINGLE_QUOTE != mTypedWord.codePointAt(i)) break; ++mTrailingSingleQuotesCount; ++mTrailingSingleQuotesCount; } } } } mCurrentWord.mAutoCorrection = null; mAutoCorrection = null; } } /** /** Loading @@ -255,7 +236,7 @@ public class WordComposer { * @return the word that was typed so far. Never returns null. * @return the word that was typed so far. Never returns null. */ */ public String getTypedWord() { public String getTypedWord() { return mCurrentWord.mTypedWord.toString(); return mTypedWord.toString(); } } /** /** Loading Loading @@ -306,14 +287,14 @@ public class WordComposer { * Sets the auto-correction for this word. * Sets the auto-correction for this word. */ */ public void setAutoCorrection(final CharSequence correction) { public void setAutoCorrection(final CharSequence correction) { mCurrentWord.mAutoCorrection = correction; mAutoCorrection = correction; } } /** /** * @return the auto-correction for this word, or null if none. * @return the auto-correction for this word, or null if none. */ */ public CharSequence getAutoCorrectionOrNull() { public CharSequence getAutoCorrectionOrNull() { return mCurrentWord.mAutoCorrection; return mAutoCorrection; } } // `type' should be one of the LastComposedWord.COMMIT_TYPE_* constants above. // `type' should be one of the LastComposedWord.COMMIT_TYPE_* constants above. Loading @@ -328,23 +309,22 @@ public class WordComposer { // LastComposedWord#didAutoCorrectToAnotherWord with #equals(). It would be marginally // LastComposedWord#didAutoCorrectToAnotherWord with #equals(). It would be marginally // cleaner to do it here, but it would be slower (since we would #equals() for each commit, // cleaner to do it here, but it would be slower (since we would #equals() for each commit, // instead of only on cancel), and ultimately we want to figure it out even earlier anyway. // instead of only on cancel), and ultimately we want to figure it out even earlier anyway. final LastComposedWord lastComposedWord = new LastComposedWord(type, mCurrentWord.mCodes, final LastComposedWord lastComposedWord = new LastComposedWord(type, mCodes, mCurrentWord.mXCoordinates, mCurrentWord.mYCoordinates, mXCoordinates, mYCoordinates, mTypedWord.toString(), mCurrentWord.mTypedWord.toString(), (type != LastComposedWord.COMMIT_TYPE_DECIDED_WORD) || (null == mAutoCorrection) (type != LastComposedWord.COMMIT_TYPE_DECIDED_WORD) ? null : mAutoCorrection.toString()); || (null == mCurrentWord.mAutoCorrection) mCodes.clear(); ? null : mCurrentWord.mAutoCorrection.toString()); mTypedWord.setLength(0); // TODO: improve performance by swapping buffers instead of creating a new object. mAutoCorrection = null; mCurrentWord = new CharacterStore(); return lastComposedWord; return lastComposedWord; } } public void resumeSuggestionOnLastComposedWord(final LastComposedWord lastComposedWord) { public void resumeSuggestionOnLastComposedWord(final LastComposedWord lastComposedWord) { mCurrentWord.mCodes = lastComposedWord.mCodes; mCodes = lastComposedWord.mCodes; mCurrentWord.mXCoordinates = lastComposedWord.mXCoordinates; mXCoordinates = lastComposedWord.mXCoordinates; mCurrentWord.mYCoordinates = lastComposedWord.mYCoordinates; mYCoordinates = lastComposedWord.mYCoordinates; mCurrentWord.mTypedWord.setLength(0); mTypedWord.setLength(0); mCurrentWord.mTypedWord.append(lastComposedWord.mTypedWord); mTypedWord.append(lastComposedWord.mTypedWord); mCurrentWord.mAutoCorrection = lastComposedWord.mAutoCorrection; mAutoCorrection = lastComposedWord.mAutoCorrection; } } } } Loading
java/src/com/android/inputmethod/latin/WordComposer.java +50 −70 Original line number Original line Diff line number Diff line Loading @@ -33,45 +33,17 @@ public class WordComposer { public static final int NOT_A_CODE = KeyDetector.NOT_A_CODE; public static final int NOT_A_CODE = KeyDetector.NOT_A_CODE; public static final int NOT_A_COORDINATE = -1; public static final int NOT_A_COORDINATE = -1; // Storage for all the info about the current input. private static class CharacterStore { /** * The list of unicode values for each keystroke (including surrounding keys) */ ArrayList<int[]> mCodes; int[] mXCoordinates; int[] mYCoordinates; StringBuilder mTypedWord; CharSequence mAutoCorrection; CharacterStore() { final int N = BinaryDictionary.MAX_WORD_LENGTH; final int N = BinaryDictionary.MAX_WORD_LENGTH; mCodes = new ArrayList<int[]>(N); mTypedWord = new StringBuilder(N); mXCoordinates = new int[N]; mYCoordinates = new int[N]; mAutoCorrection = null; } CharacterStore(final CharacterStore that) { mCodes = new ArrayList<int[]>(that.mCodes); mTypedWord = new StringBuilder(that.mTypedWord); mXCoordinates = Arrays.copyOf(that.mXCoordinates, that.mXCoordinates.length); mYCoordinates = Arrays.copyOf(that.mYCoordinates, that.mYCoordinates.length); } void reset() { // For better performance than creating a new character store. mCodes.clear(); mTypedWord.setLength(0); mAutoCorrection = null; } } // The currently typing word. May not be null. private ArrayList<int[]> mCodes; private CharacterStore mCurrentWord; private int[] mXCoordinates; private int[] mYCoordinates; private StringBuilder mTypedWord; private CharSequence mAutoCorrection; // Cache these values for performance private int mCapsCount; private int mCapsCount; private boolean mAutoCapitalized; private boolean mAutoCapitalized; // Cache this value for performance private int mTrailingSingleQuotesCount; private int mTrailingSingleQuotesCount; /** /** Loading @@ -80,7 +52,11 @@ public class WordComposer { private boolean mIsFirstCharCapitalized; private boolean mIsFirstCharCapitalized; public WordComposer() { public WordComposer() { mCurrentWord = new CharacterStore(); mCodes = new ArrayList<int[]>(N); mTypedWord = new StringBuilder(N); mXCoordinates = new int[N]; mYCoordinates = new int[N]; mAutoCorrection = null; mTrailingSingleQuotesCount = 0; mTrailingSingleQuotesCount = 0; } } Loading @@ -89,7 +65,10 @@ public class WordComposer { } } public void init(WordComposer source) { public void init(WordComposer source) { mCurrentWord = new CharacterStore(source.mCurrentWord); mCodes = new ArrayList<int[]>(source.mCodes); mTypedWord = new StringBuilder(source.mTypedWord); mXCoordinates = Arrays.copyOf(source.mXCoordinates, source.mXCoordinates.length); mYCoordinates = Arrays.copyOf(source.mYCoordinates, source.mYCoordinates.length); mCapsCount = source.mCapsCount; mCapsCount = source.mCapsCount; mIsFirstCharCapitalized = source.mIsFirstCharCapitalized; mIsFirstCharCapitalized = source.mIsFirstCharCapitalized; mAutoCapitalized = source.mAutoCapitalized; mAutoCapitalized = source.mAutoCapitalized; Loading @@ -100,7 +79,9 @@ public class WordComposer { * Clear out the keys registered so far. * Clear out the keys registered so far. */ */ public void reset() { public void reset() { mCurrentWord.reset(); mCodes.clear(); mTypedWord.setLength(0); mAutoCorrection = null; mCapsCount = 0; mCapsCount = 0; mIsFirstCharCapitalized = false; mIsFirstCharCapitalized = false; mTrailingSingleQuotesCount = 0; mTrailingSingleQuotesCount = 0; Loading @@ -111,7 +92,7 @@ public class WordComposer { * @return the number of keystrokes * @return the number of keystrokes */ */ public final int size() { public final int size() { return mCurrentWord.mTypedWord.length(); return mTypedWord.length(); } } public final boolean isComposingWord() { public final boolean isComposingWord() { Loading @@ -124,15 +105,15 @@ public class WordComposer { * @return the unicode for the pressed and surrounding keys * @return the unicode for the pressed and surrounding keys */ */ public int[] getCodesAt(int index) { public int[] getCodesAt(int index) { return mCurrentWord.mCodes.get(index); return mCodes.get(index); } } public int[] getXCoordinates() { public int[] getXCoordinates() { return mCurrentWord.mXCoordinates; return mXCoordinates; } } public int[] getYCoordinates() { public int[] getYCoordinates() { return mCurrentWord.mYCoordinates; return mYCoordinates; } } private static boolean isFirstCharCapitalized(int index, int codePoint, boolean previous) { private static boolean isFirstCharCapitalized(int index, int codePoint, boolean previous) { Loading @@ -147,12 +128,12 @@ public class WordComposer { */ */ public void add(int primaryCode, int[] codes, int x, int y) { public void add(int primaryCode, int[] codes, int x, int y) { final int newIndex = size(); final int newIndex = size(); mCurrentWord.mTypedWord.append((char) primaryCode); mTypedWord.append((char) primaryCode); correctPrimaryJuxtapos(primaryCode, codes); correctPrimaryJuxtapos(primaryCode, codes); mCurrentWord.mCodes.add(codes); mCodes.add(codes); if (newIndex < BinaryDictionary.MAX_WORD_LENGTH) { if (newIndex < BinaryDictionary.MAX_WORD_LENGTH) { mCurrentWord.mXCoordinates[newIndex] = x; mXCoordinates[newIndex] = x; mCurrentWord.mYCoordinates[newIndex] = y; mYCoordinates[newIndex] = y; } } mIsFirstCharCapitalized = isFirstCharCapitalized( mIsFirstCharCapitalized = isFirstCharCapitalized( newIndex, primaryCode, mIsFirstCharCapitalized); newIndex, primaryCode, mIsFirstCharCapitalized); Loading @@ -162,7 +143,7 @@ public class WordComposer { } else { } else { mTrailingSingleQuotesCount = 0; mTrailingSingleQuotesCount = 0; } } mCurrentWord.mAutoCorrection = null; mAutoCorrection = null; } } /** /** Loading Loading @@ -231,9 +212,9 @@ public class WordComposer { final int size = size(); final int size = size(); if (size > 0) { if (size > 0) { final int lastPos = size - 1; final int lastPos = size - 1; char lastChar = mCurrentWord.mTypedWord.charAt(lastPos); char lastChar = mTypedWord.charAt(lastPos); mCurrentWord.mCodes.remove(lastPos); mCodes.remove(lastPos); mCurrentWord.mTypedWord.deleteCharAt(lastPos); mTypedWord.deleteCharAt(lastPos); if (Character.isUpperCase(lastChar)) mCapsCount--; if (Character.isUpperCase(lastChar)) mCapsCount--; } } if (size() == 0) { if (size() == 0) { Loading @@ -242,12 +223,12 @@ public class WordComposer { if (mTrailingSingleQuotesCount > 0) { if (mTrailingSingleQuotesCount > 0) { --mTrailingSingleQuotesCount; --mTrailingSingleQuotesCount; } else { } else { for (int i = mCurrentWord.mTypedWord.length() - 1; i >= 0; --i) { for (int i = mTypedWord.length() - 1; i >= 0; --i) { if (Keyboard.CODE_SINGLE_QUOTE != mCurrentWord.mTypedWord.codePointAt(i)) break; if (Keyboard.CODE_SINGLE_QUOTE != mTypedWord.codePointAt(i)) break; ++mTrailingSingleQuotesCount; ++mTrailingSingleQuotesCount; } } } } mCurrentWord.mAutoCorrection = null; mAutoCorrection = null; } } /** /** Loading @@ -255,7 +236,7 @@ public class WordComposer { * @return the word that was typed so far. Never returns null. * @return the word that was typed so far. Never returns null. */ */ public String getTypedWord() { public String getTypedWord() { return mCurrentWord.mTypedWord.toString(); return mTypedWord.toString(); } } /** /** Loading Loading @@ -306,14 +287,14 @@ public class WordComposer { * Sets the auto-correction for this word. * Sets the auto-correction for this word. */ */ public void setAutoCorrection(final CharSequence correction) { public void setAutoCorrection(final CharSequence correction) { mCurrentWord.mAutoCorrection = correction; mAutoCorrection = correction; } } /** /** * @return the auto-correction for this word, or null if none. * @return the auto-correction for this word, or null if none. */ */ public CharSequence getAutoCorrectionOrNull() { public CharSequence getAutoCorrectionOrNull() { return mCurrentWord.mAutoCorrection; return mAutoCorrection; } } // `type' should be one of the LastComposedWord.COMMIT_TYPE_* constants above. // `type' should be one of the LastComposedWord.COMMIT_TYPE_* constants above. Loading @@ -328,23 +309,22 @@ public class WordComposer { // LastComposedWord#didAutoCorrectToAnotherWord with #equals(). It would be marginally // LastComposedWord#didAutoCorrectToAnotherWord with #equals(). It would be marginally // cleaner to do it here, but it would be slower (since we would #equals() for each commit, // cleaner to do it here, but it would be slower (since we would #equals() for each commit, // instead of only on cancel), and ultimately we want to figure it out even earlier anyway. // instead of only on cancel), and ultimately we want to figure it out even earlier anyway. final LastComposedWord lastComposedWord = new LastComposedWord(type, mCurrentWord.mCodes, final LastComposedWord lastComposedWord = new LastComposedWord(type, mCodes, mCurrentWord.mXCoordinates, mCurrentWord.mYCoordinates, mXCoordinates, mYCoordinates, mTypedWord.toString(), mCurrentWord.mTypedWord.toString(), (type != LastComposedWord.COMMIT_TYPE_DECIDED_WORD) || (null == mAutoCorrection) (type != LastComposedWord.COMMIT_TYPE_DECIDED_WORD) ? null : mAutoCorrection.toString()); || (null == mCurrentWord.mAutoCorrection) mCodes.clear(); ? null : mCurrentWord.mAutoCorrection.toString()); mTypedWord.setLength(0); // TODO: improve performance by swapping buffers instead of creating a new object. mAutoCorrection = null; mCurrentWord = new CharacterStore(); return lastComposedWord; return lastComposedWord; } } public void resumeSuggestionOnLastComposedWord(final LastComposedWord lastComposedWord) { public void resumeSuggestionOnLastComposedWord(final LastComposedWord lastComposedWord) { mCurrentWord.mCodes = lastComposedWord.mCodes; mCodes = lastComposedWord.mCodes; mCurrentWord.mXCoordinates = lastComposedWord.mXCoordinates; mXCoordinates = lastComposedWord.mXCoordinates; mCurrentWord.mYCoordinates = lastComposedWord.mYCoordinates; mYCoordinates = lastComposedWord.mYCoordinates; mCurrentWord.mTypedWord.setLength(0); mTypedWord.setLength(0); mCurrentWord.mTypedWord.append(lastComposedWord.mTypedWord); mTypedWord.append(lastComposedWord.mTypedWord); mCurrentWord.mAutoCorrection = lastComposedWord.mAutoCorrection; mAutoCorrection = lastComposedWord.mAutoCorrection; } } } }