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)); |