Optimisations and bugs in SpellChecker

A bug was introduced in a recent refactoring: correct words didn't have their
SpellCheckSpan removed, leaving a lot of useless spans.

SPAN_EXCLUSIVE_EXCLUSIVE should never have a 0-length. With Japanese characters
wordStart could be equal to wordEnd when parsing the text: skip these.

Using toString().substring(...) instead of subSequence(...).toString() which
is more efficient.

Change-Id: I670870a34565939b676400091f4852152a7f7124
This commit is contained in:
Gilles Debunne
2011-10-03 17:01:19 -07:00
parent f00b4decc3
commit e1fc4f6c3c
2 changed files with 15 additions and 13 deletions

View File

@@ -165,6 +165,7 @@ public class SpellChecker implements SpellCheckerSessionListener {
@Override
public void onGetSuggestions(SuggestionsInfo[] results) {
final Editable editable = (Editable) mTextView.getText();
for (int i = 0; i < results.length; i++) {
SuggestionsInfo suggestionsInfo = results[i];
if (suggestionsInfo.getCookie() != mCookie) continue;
@@ -178,18 +179,19 @@ public class SpellChecker implements SpellCheckerSessionListener {
boolean looksLikeTypo =
((attributes & SuggestionsInfo.RESULT_ATTR_LOOKS_LIKE_TYPO) > 0);
SpellCheckSpan spellCheckSpan = mSpellCheckSpans[j];
if (!isInDictionary && looksLikeTypo) {
createMisspelledSuggestionSpan(suggestionsInfo, mSpellCheckSpans[j]);
createMisspelledSuggestionSpan(editable, suggestionsInfo, spellCheckSpan);
}
editable.removeSpan(spellCheckSpan);
break;
}
}
}
}
private void createMisspelledSuggestionSpan(SuggestionsInfo suggestionsInfo,
private void createMisspelledSuggestionSpan(Editable editable, SuggestionsInfo suggestionsInfo,
SpellCheckSpan spellCheckSpan) {
final Editable editable = (Editable) mTextView.getText();
final int start = editable.getSpanStart(spellCheckSpan);
final int end = editable.getSpanEnd(spellCheckSpan);
@@ -251,6 +253,5 @@ public class SpellChecker implements SpellCheckerSessionListener {
// TODO limit to the word rectangle region
mTextView.invalidate();
editable.removeSpan(spellCheckSpan);
}
}

View File

@@ -7780,7 +7780,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
// Iterate over the newly added text and schedule new SpellCheckSpans
while (wordStart <= shiftedEnd) {
if (wordEnd >= shiftedStart) {
if (wordEnd >= shiftedStart && wordEnd > wordStart) {
// A new word has been created across the interval boundaries. Remove previous spans
if (wordStart < shiftedStart && wordEnd > shiftedStart) {
removeSpansAt(start, spellCheckSpans, text);
@@ -9946,8 +9946,8 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
suggestionInfo.text.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
// Add the text before and after the span.
suggestionInfo.text.insert(0, mText.subSequence(unionStart, spanStart).toString());
suggestionInfo.text.append(mText.subSequence(spanEnd, unionEnd).toString());
suggestionInfo.text.insert(0, mText.toString().substring(unionStart, spanStart));
suggestionInfo.text.append(mText.toString().substring(spanEnd, unionEnd));
}
@Override
@@ -9979,7 +9979,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
hide();
return;
}
final String originalText = mText.subSequence(spanStart, spanEnd).toString();
final String originalText = mText.toString().substring(spanStart, spanEnd);
if (suggestionInfo.suggestionIndex == ADD_TO_DICTIONARY) {
Intent intent = new Intent(Settings.ACTION_USER_DICTIONARY_INSERT);
@@ -10016,8 +10016,10 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
if (!TextUtils.isEmpty(
suggestionInfo.suggestionSpan.getNotificationTargetClassName())) {
InputMethodManager imm = InputMethodManager.peekInstance();
imm.notifySuggestionPicked(suggestionInfo.suggestionSpan, originalText,
suggestionInfo.suggestionIndex);
if (imm != null) {
imm.notifySuggestionPicked(suggestionInfo.suggestionSpan, originalText,
suggestionInfo.suggestionIndex);
}
}
// Swap text content between actual text and Suggestion span
@@ -10037,7 +10039,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
}
}
// Move cursor at the end of the replacement word
// Move cursor at the end of the replaced word
Selection.setSelection(editable, spanEnd + lengthDifference);
}
@@ -10166,8 +10168,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
if (!hasSelection()) {
// There may already be a selection on device rotation
boolean currentWordSelected = selectCurrentWord();
if (!currentWordSelected) {
if (!selectCurrentWord()) {
// No word found under cursor or text selection not permitted.
return false;
}