Chromium Code Reviews| Index: content/browser/renderer_host/ime_adapter_android.cc |
| diff --git a/content/browser/renderer_host/ime_adapter_android.cc b/content/browser/renderer_host/ime_adapter_android.cc |
| index a19e7f44e2cbca612142ae59f0ee3fe84fe622c2..d72542a868660d96f5108d8ff18ab280d6734762 100644 |
| --- a/content/browser/renderer_host/ime_adapter_android.cc |
| +++ b/content/browser/renderer_host/ime_adapter_android.cc |
| @@ -4,6 +4,7 @@ |
| #include "content/browser/renderer_host/ime_adapter_android.h" |
| +#include <algorithm> |
| #include <android/input.h> |
| #include "base/android/jni_android.h" |
| @@ -57,6 +58,52 @@ NativeWebKeyboardEvent NativeWebKeyboardEventFromKeyEvent( |
| time_ms / 1000.0, key_code, unicode_char, is_system_key); |
| } |
| +// Uses JNI to iterate over |spanObjArray| obtianed from |spannableString|, and |
| +// populates a list of blink::WebCompositionUnderline with data from spans |
| +// that we care about (e.g., BackgroundColorSpan). |
| +void GetUnderlinesFromSpanArray( |
| + JNIEnv* env, |
| + jobject spannableString, |
| + jobjectArray spanObjArray, |
| + std::vector<blink::WebCompositionUnderline>* underlines) { |
| + if (!spannableString || !spanObjArray) |
| + return; |
| + |
| + jclass clsSpannableString = env->FindClass("android/text/SpannableString"); |
|
aurimas (slooooooooow)
2014/06/10 00:30:48
In Chrome for Android we avoid using JNI FindClass
huangs
2014/06/10 04:39:13
Done.
|
| + jclass clsBackgroundColorSpan = |
| + env->FindClass("android/text/style/BackgroundColorSpan"); |
| + if (!clsSpannableString || !clsBackgroundColorSpan) |
| + return; |
| + |
| + jmethodID midGetSpanStart = env->GetMethodID( |
| + clsSpannableString, "getSpanStart", "(Ljava/lang/Object;)I"); |
| + jmethodID midGetSpanEnd = env->GetMethodID( |
| + clsSpannableString, "getSpanEnd", "(Ljava/lang/Object;)I"); |
| + jmethodID midGetBackgroundColor = env->GetMethodID( |
| + clsBackgroundColorSpan, "getBackgroundColor", "()I"); |
| + |
| + if (!midGetSpanStart || !midGetSpanEnd || !midGetBackgroundColor) |
| + return; |
| + |
| + jsize n = env->GetArrayLength(spanObjArray); |
| + for (int i = 0; i < n; ++i) { |
| + jobject spanObj = env->GetObjectArrayElement(spanObjArray, i); |
| + if (env->IsInstanceOf(spanObj, clsBackgroundColorSpan) == JNI_FALSE) |
| + continue; |
| + |
| + jint start = env->CallIntMethod(spannableString, midGetSpanStart, spanObj); |
| + jint end = env->CallIntMethod(spannableString, midGetSpanEnd, spanObj); |
| + jint background = env->CallIntMethod(spanObj, midGetBackgroundColor); |
| + |
| + underlines->push_back(blink::WebCompositionUnderline( |
| + static_cast<int>(start), |
| + static_cast<int>(end), |
| + SK_ColorBLACK, |
| + false, |
| + background)); |
| + } |
| +} |
| + |
| } // anonymous namespace |
| bool RegisterImeAdapter(JNIEnv* env) { |
| @@ -138,17 +185,30 @@ bool ImeAdapterAndroid::SendKeyEvent(JNIEnv* env, jobject, |
| return true; |
| } |
| -void ImeAdapterAndroid::SetComposingText(JNIEnv* env, jobject, jstring text, |
| - int new_cursor_pos) { |
| +void ImeAdapterAndroid::SetComposingText(JNIEnv* env, |
| + jobject, |
| + jstring text, |
| + int new_cursor_pos, |
| + jobject spannableString, |
| + jobjectArray spanObjArray) { |
| RenderWidgetHostImpl* rwhi = GetRenderWidgetHostImpl(); |
| if (!rwhi) |
| return; |
| base::string16 text16 = ConvertJavaStringToUTF16(env, text); |
| std::vector<blink::WebCompositionUnderline> underlines; |
| - underlines.push_back( |
| - blink::WebCompositionUnderline(0, text16.length(), SK_ColorBLACK, |
| - false)); |
| + |
| + GetUnderlinesFromSpanArray(env, spannableString, spanObjArray, &underlines); |
|
aurimas (slooooooooow)
2014/06/10 00:30:49
Here you should call Java_ImeAdapter_getUnderlines
huangs
2014/06/10 04:39:13
Done. I'm looping over Object[] because in the ne
|
| + |
| + // Default to simple underline if we find no spans that we care about. |
| + if (underlines.empty()) { |
| + underlines.push_back( |
| + blink::WebCompositionUnderline(0, text16.length(), SK_ColorBLACK, false, |
| + SK_ColorTRANSPARENT)); |
| + } |
| + // Sort spans by |.startOffset|. |
| + std::sort(underlines.begin(), underlines.end()); |
| + |
| // new_cursor_position is as described in the Android API for |
| // InputConnection#setComposingText, whereas the parameters for |
| // ImeSetComposition are relative to the start of the composition. |
| @@ -215,7 +275,8 @@ void ImeAdapterAndroid::SetComposingRegion(JNIEnv*, jobject, |
| std::vector<blink::WebCompositionUnderline> underlines; |
| underlines.push_back( |
| - blink::WebCompositionUnderline(0, end - start, SK_ColorBLACK, false)); |
| + blink::WebCompositionUnderline(0, end - start, SK_ColorBLACK, false, |
| + SK_ColorTRANSPARENT)); |
| rfh->Send(new FrameMsg_SetCompositionFromExistingText( |
| rfh->GetRoutingID(), start, end, underlines)); |