From f3c319fb8ac29448c491af95261a4ce01b64a59c Mon Sep 17 00:00:00 2001 From: Dan Zivkovic Date: Wed, 4 Feb 2015 16:12:15 -0800 Subject: Selections spans should not split surrogate pair. When committing a span after a revert, the offset logic was such that it split a surrogate unicode pair used to express an emoji. Checking the last character of the span lets us avoid this problem. Fix for bug 19255233. Change-Id: I07d18d9002b5075f7925319dd05962011656c311 --- .../inputmethod/latin/RichInputConnection.java | 25 +++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) (limited to 'java') diff --git a/java/src/com/android/inputmethod/latin/RichInputConnection.java b/java/src/com/android/inputmethod/latin/RichInputConnection.java index 2cf476f8b..f770e88ef 100644 --- a/java/src/com/android/inputmethod/latin/RichInputConnection.java +++ b/java/src/com/android/inputmethod/latin/RichInputConnection.java @@ -21,6 +21,7 @@ import android.os.Build; import android.os.Bundle; import android.text.SpannableStringBuilder; import android.text.TextUtils; +import android.text.style.CharacterStyle; import android.util.Log; import android.view.KeyEvent; import android.view.inputmethod.CompletionInfo; @@ -32,6 +33,7 @@ import android.view.inputmethod.InputMethodManager; import com.android.inputmethod.compat.InputConnectionCompatUtils; import com.android.inputmethod.latin.common.Constants; +import com.android.inputmethod.latin.common.UnicodeSurrogate; import com.android.inputmethod.latin.common.StringUtils; import com.android.inputmethod.latin.inputlogic.PrivateCommandPerformer; import com.android.inputmethod.latin.settings.SpacingAndPunctuations; @@ -261,7 +263,28 @@ public final class RichInputConnection implements PrivateCommandPerformer { mComposingText.setLength(0); mLastCommittedTextHasBackgroundColor = false; if (null != mIC) { - mIC.commitText(text, newCursorPosition); + mTempObjectForCommitText.clear(); + mTempObjectForCommitText.append(text); + final CharacterStyle[] spans = mTempObjectForCommitText.getSpans( + 0, text.length(), CharacterStyle.class); + for (final CharacterStyle span : spans) { + final int spanStart = mTempObjectForCommitText.getSpanStart(span); + final int spanEnd = mTempObjectForCommitText.getSpanEnd(span); + final int spanFlags = mTempObjectForCommitText.getSpanFlags(span); + // We have to adjust the end of the span to include an additional character. + // This is to avoid splitting a unicode surrogate pair. + // See com.android.inputmethod.latin.common.Constants.UnicodeSurrogate + // See https://b.corp.google.com/issues/19255233 + if (0 < spanEnd && spanEnd < mTempObjectForCommitText.length()) { + final char spanEndChar = mTempObjectForCommitText.charAt(spanEnd - 1); + final char nextChar = mTempObjectForCommitText.charAt(spanEnd); + if (UnicodeSurrogate.isLowSurrogate(spanEndChar) + && UnicodeSurrogate.isHighSurrogate(nextChar)) { + mTempObjectForCommitText.setSpan(span, spanStart, spanEnd + 1, spanFlags); + } + } + } + mIC.commitText(mTempObjectForCommitText, newCursorPosition); } } -- cgit v1.2.3-83-g751a