diff options
author | 2013-06-24 19:43:03 +0900 | |
---|---|---|
committer | 2013-06-26 23:02:50 +0900 | |
commit | 2f7f6257b66fc1ed19b600f3d55902fd0de2e338 (patch) | |
tree | 2826b91078f36338b08774c3ba40c5a691584b2c /java | |
parent | a690f3bc40268ccee20c44c7e359890b34eb2a8a (diff) | |
download | latinime-2f7f6257b66fc1ed19b600f3d55902fd0de2e338.tar.gz latinime-2f7f6257b66fc1ed19b600f3d55902fd0de2e338.tar.xz latinime-2f7f6257b66fc1ed19b600f3d55902fd0de2e338.zip |
Ignore spans that are not the right size.
Bug: 8839763
Bug: 8862327
Change-Id: I5d49c86edcbc0fc1b2b147856437cfbadd678377
Diffstat (limited to 'java')
-rw-r--r-- | java/src/com/android/inputmethod/latin/LatinIME.java | 25 | ||||
-rw-r--r-- | java/src/com/android/inputmethod/latin/RichInputConnection.java | 63 |
2 files changed, 72 insertions, 16 deletions
diff --git a/java/src/com/android/inputmethod/latin/LatinIME.java b/java/src/com/android/inputmethod/latin/LatinIME.java index c867436e5..824752fcb 100644 --- a/java/src/com/android/inputmethod/latin/LatinIME.java +++ b/java/src/com/android/inputmethod/latin/LatinIME.java @@ -43,7 +43,6 @@ import android.os.Message; import android.os.SystemClock; import android.preference.PreferenceManager; import android.text.InputType; -import android.text.Spanned; import android.text.TextUtils; import android.text.style.SuggestionSpan; import android.util.Log; @@ -2522,21 +2521,15 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen final int numberOfCharsInWordBeforeCursor = range.getNumberOfCharsInWordBeforeCursor(); if (numberOfCharsInWordBeforeCursor > mLastSelectionStart) return; final ArrayList<SuggestedWordInfo> suggestions = CollectionUtils.newArrayList(); - final CharSequence word = range.mWord; - final String typedWord = word.toString(); - if (word instanceof Spanned) { - final Spanned spanned = (Spanned)word; - int i = 0; - for (Object object : spanned.getSpans(0, spanned.length(), - SuggestionSpan.class)) { - SuggestionSpan span = (SuggestionSpan)object; - for (String s : span.getSuggestions()) { - ++i; - if (!TextUtils.equals(s, typedWord)) { - suggestions.add(new SuggestedWordInfo(s, - SuggestionStripView.MAX_SUGGESTIONS - i, - SuggestedWordInfo.KIND_RESUMED, Dictionary.TYPE_RESUMED)); - } + final String typedWord = range.mWord.toString(); + int i = 0; + for (final SuggestionSpan span : range.getSuggestionSpansAtWord()) { + for (final String s : span.getSuggestions()) { + ++i; + if (!TextUtils.equals(s, typedWord)) { + suggestions.add(new SuggestedWordInfo(s, + SuggestionStripView.MAX_SUGGESTIONS - i, + SuggestedWordInfo.KIND_RESUMED, Dictionary.TYPE_RESUMED)); } } } diff --git a/java/src/com/android/inputmethod/latin/RichInputConnection.java b/java/src/com/android/inputmethod/latin/RichInputConnection.java index 5391b1303..6b22cb12e 100644 --- a/java/src/com/android/inputmethod/latin/RichInputConnection.java +++ b/java/src/com/android/inputmethod/latin/RichInputConnection.java @@ -17,7 +17,9 @@ package com.android.inputmethod.latin; import android.inputmethodservice.InputMethodService; +import android.text.Spanned; import android.text.TextUtils; +import android.text.style.SuggestionSpan; import android.util.Log; import android.view.KeyEvent; import android.view.inputmethod.CompletionInfo; @@ -32,6 +34,7 @@ import com.android.inputmethod.latin.utils.DebugLogUtils; import com.android.inputmethod.latin.utils.StringUtils; import com.android.inputmethod.research.ResearchLogger; +import java.util.Arrays; import java.util.Locale; import java.util.regex.Pattern; @@ -457,6 +460,66 @@ public final class RichInputConnection { return mWordAtCursorEndIndex - mCursorIndex; } + /** + * Gets the suggestion spans that are put squarely on the word, with the exact start + * and end of the span matching the boundaries of the word. + * @return the list of spans. + */ + public SuggestionSpan[] getSuggestionSpansAtWord() { + if (!(mTextAtCursor instanceof Spanned && mWord instanceof Spanned)) { + return new SuggestionSpan[0]; + } + final Spanned text = (Spanned)mTextAtCursor; + // Note: it's fine to pass indices negative or greater than the length of the string + // to the #getSpans() method. The reason we need to get from -1 to +1 is that, the + // spans were cut at the cursor position, and #getSpans(start, end) does not return + // spans that end at `start' or begin at `end'. Consider the following case: + // this| is (The | symbolizes the cursor position + // ---- --- + // In this case, the cursor is in position 4, so the 0~7 span has been split into + // a 0~4 part and a 4~7 part. + // If we called #getSpans(0, 4) in this case, we would only get the part from 0 to 4 + // of the span, and not the part from 4 to 7, so we would not realize the span actually + // extends from 0 to 7. But if we call #getSpans(-1, 5) we'll get both the 0~4 and + // the 4~7 spans and we can merge them accordingly. + // Any span starting more than 1 char away from the word boundaries in any direction + // does not touch the word, so we don't need to consider it. That's why requesting + // -1 ~ +1 is enough. + // Of course this is only relevant if the cursor is at one end of the word. If it's + // in the middle, the -1 and +1 are not necessary, but they are harmless. + final SuggestionSpan[] spans = text.getSpans(mWordAtCursorStartIndex - 1, + mWordAtCursorEndIndex + 1, SuggestionSpan.class); + int readIndex = 0; + int writeIndex = 0; + for (; readIndex < spans.length; ++readIndex) { + final SuggestionSpan span = spans[readIndex]; + // The span may be null, as we null them when we find duplicates. Cf a few lines + // down. + if (null == span) continue; + // Tentative span start and end. This may be modified later if we realize the + // same span is also applied to other parts of the string. + int spanStart = text.getSpanStart(span); + int spanEnd = text.getSpanEnd(span); + for (int i = readIndex + 1; i < spans.length; ++i) { + if (span.equals(spans[i])) { + // We found the same span somewhere else. Read the new extent of this + // span, and adjust our values accordingly. + spanStart = Math.min(spanStart, text.getSpanStart(spans[i])); + spanEnd = Math.max(spanEnd, text.getSpanEnd(spans[i])); + // ...and mark the span as processed. + spans[i] = null; + } + } + if (spanStart == mWordAtCursorStartIndex && spanEnd == mWordAtCursorEndIndex) { + // If the span does not start and stop here, we ignore it. It probably extends + // past the start or end of the word, as happens in missing space correction + // or EasyEditSpans put by voice input. + spans[writeIndex++] = spans[readIndex]; + } + } + return writeIndex == readIndex ? spans : Arrays.copyOfRange(spans, 0, writeIndex); + } + public Range(final CharSequence textAtCursor, final int wordAtCursorStartIndex, final int wordAtCursorEndIndex, final int cursorIndex) { if (wordAtCursorStartIndex < 0 || cursorIndex < wordAtCursorStartIndex |