Index: ui/base/ime/android/cursor_anchor_info_builder.cc |
diff --git a/ui/base/ime/android/cursor_anchor_info_builder.cc b/ui/base/ime/android/cursor_anchor_info_builder.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..6ece71e194787d838511cca704690c2b408365f7 |
--- /dev/null |
+++ b/ui/base/ime/android/cursor_anchor_info_builder.cc |
@@ -0,0 +1,157 @@ |
+// Copyright 2014 The Chromium Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+#include "ui/base/ime/android/cursor_anchor_info_builder.h" |
+ |
+#include "base/android/jni_android.h" |
+#include "base/android/jni_string.h" |
+#include "base/android/jni_weak_ref.h" |
+#include "base/android/scoped_java_ref.h" |
+#include "base/containers/mru_cache.h" |
+#include "jni/CursorAnchorInfoBuilder_jni.h" |
+ |
+namespace ui { |
+namespace { |
+ |
+using base::android::AttachCurrentThread; |
+ |
+const size_t kComposingTextCacheSize = 2; |
+ |
+class CursorAnchorInfoBuilderImpl final |
+ : public CursorAnchorInfoBuilder { |
+ public: |
+ CursorAnchorInfoBuilderImpl(); |
+ ~CursorAnchorInfoBuilderImpl() override; |
+ |
+ void AddCharacterBounds(int index, |
+ const gfx::RectF& rect, |
+ uint32 flags) override; |
+ base::android::ScopedJavaLocalRef<jobject> Build() override; |
+ void Reset() override; |
+ void SetComposingText(int composingTextStart, |
+ base::StringPiece16 composingText) override; |
+ void SetInsertionMarkerLocation(float horizontalPosition, |
+ float lineTop, |
+ float lineBaseline, |
+ float lineBottom, |
+ uint32 flags) override; |
+ void SetScaleAndTranslate(float scale, |
+ const gfx::Vector2dF& translate) override; |
+ void SetSelectionRange(const gfx::Range& range) override; |
+ |
+ static bool Register(JNIEnv* env); |
+ |
+ private: |
+ base::android::ScopedJavaGlobalRef<jobject> builder_; |
+ base::MRUCache<base::string16, base::android::ScopedJavaGlobalRef<jstring>> |
+ composing_text_cache_; |
+ |
+ DISALLOW_COPY_AND_ASSIGN(CursorAnchorInfoBuilderImpl); |
+}; |
+ |
+CursorAnchorInfoBuilderImpl::CursorAnchorInfoBuilderImpl() |
+ : builder_(Java_CursorAnchorInfoBuilder_create(AttachCurrentThread())), |
+ composing_text_cache_(kComposingTextCacheSize) { |
+} |
+ |
+CursorAnchorInfoBuilderImpl::~CursorAnchorInfoBuilderImpl() { |
+} |
+ |
+void CursorAnchorInfoBuilderImpl::AddCharacterBounds( |
+ int index, const gfx::RectF& rect, uint32 flags) { |
+ JNIEnv* env = AttachCurrentThread(); |
+ Java_CursorAnchorInfoBuilder_addCharacterBounds( |
+ env, |
+ builder_.obj(), |
+ index, |
+ rect.x(), |
+ rect.y(), |
+ rect.right(), |
+ rect.bottom(), |
+ flags); |
+} |
+ |
+base::android::ScopedJavaLocalRef<jobject> |
+CursorAnchorInfoBuilderImpl::Build() { |
+ JNIEnv* env = AttachCurrentThread(); |
+ return Java_CursorAnchorInfoBuilder_build(env, builder_.obj()); |
+} |
+ |
+void CursorAnchorInfoBuilderImpl::Reset() { |
+ JNIEnv* env = AttachCurrentThread(); |
+ Java_CursorAnchorInfoBuilder_reset(env, builder_.obj()); |
+} |
+ |
+void CursorAnchorInfoBuilderImpl::SetComposingText( |
+ int composing_text_start, base::StringPiece16 composing_text) { |
+ JNIEnv* env = AttachCurrentThread(); |
+ const auto& key = composing_text.as_string(); |
+ auto it = composing_text_cache_.Get(key); |
+ if (it != composing_text_cache_.end()) { |
+ Java_CursorAnchorInfoBuilder_setComposingText( |
+ env, builder_.obj(), composing_text_start, it->second.obj()); |
+ } else { |
+ auto jstr = base::android::ConvertUTF16ToJavaString(env, composing_text); |
+ Java_CursorAnchorInfoBuilder_setComposingText( |
+ env, builder_.obj(), composing_text_start, jstr.obj()); |
+ composing_text_cache_.Put( |
+ key, base::android::ScopedJavaGlobalRef<jstring>(jstr)); |
+ } |
+} |
+ |
+void CursorAnchorInfoBuilderImpl::SetInsertionMarkerLocation( |
+ float horizontalPosition, |
+ float lineTop, |
+ float lineBaseline, |
+ float lineBottom, |
+ uint32 flags) { |
+ JNIEnv* env = AttachCurrentThread(); |
+ Java_CursorAnchorInfoBuilder_setInsertionMarkerLocation( |
+ env, |
+ builder_.obj(), |
+ horizontalPosition, |
+ lineTop, |
+ lineBaseline, |
+ lineBottom, |
+ static_cast<jint>(flags)); |
+} |
+ |
+void CursorAnchorInfoBuilderImpl::SetScaleAndTranslate( |
+ float scale, |
+ const gfx::Vector2dF& translate) { |
+ JNIEnv* env = AttachCurrentThread(); |
+ Java_CursorAnchorInfoBuilder_setScaleAndTranslate( |
+ env, |
+ builder_.obj(), |
+ scale, |
+ translate.x(), |
+ translate.y()); |
+} |
+ |
+void CursorAnchorInfoBuilderImpl::SetSelectionRange(const gfx::Range& range) { |
+ JNIEnv* env = AttachCurrentThread(); |
+ Java_CursorAnchorInfoBuilder_setSelectionRange( |
+ env, builder_.obj(), range.start(), range.end()); |
+} |
+ |
+} // namespace |
+ |
+CursorAnchorInfoBuilder::CursorAnchorInfoBuilder() { |
+} |
+ |
+CursorAnchorInfoBuilder::~CursorAnchorInfoBuilder() { |
+} |
+ |
+// static |
+scoped_ptr<CursorAnchorInfoBuilder> |
+CursorAnchorInfoBuilder::Create() { |
+ return scoped_ptr<CursorAnchorInfoBuilder>(new CursorAnchorInfoBuilderImpl); |
+} |
+ |
+// static |
+bool CursorAnchorInfoBuilder::Register(JNIEnv* env) { |
+ return RegisterNativesImpl(env); |
+} |
+ |
+} // namespace ui |