diff options
Diffstat (limited to 'core/jni')
-rw-r--r-- | core/jni/Android.mk | 1 | ||||
-rw-r--r-- | core/jni/AndroidRuntime.cpp | 2 | ||||
-rw-r--r-- | core/jni/android_text_StaticLayout.cpp | 110 |
3 files changed, 113 insertions, 0 deletions
diff --git a/core/jni/Android.mk b/core/jni/Android.mk index 2e0acb1..01517b2 100644 --- a/core/jni/Android.mk +++ b/core/jni/Android.mk @@ -62,6 +62,7 @@ LOCAL_SRC_FILES:= \ android_view_VelocityTracker.cpp \ android_text_AndroidCharacter.cpp \ android_text_AndroidBidi.cpp \ + android_text_StaticLayout.cpp \ android_os_Debug.cpp \ android_os_MemoryFile.cpp \ android_os_MessageQueue.cpp \ diff --git a/core/jni/AndroidRuntime.cpp b/core/jni/AndroidRuntime.cpp index b4599b6..ead3cbe 100644 --- a/core/jni/AndroidRuntime.cpp +++ b/core/jni/AndroidRuntime.cpp @@ -149,6 +149,7 @@ extern int register_android_net_NetworkUtils(JNIEnv* env); extern int register_android_net_TrafficStats(JNIEnv* env); extern int register_android_net_wifi_WifiNative(JNIEnv* env); extern int register_android_text_AndroidCharacter(JNIEnv *env); +extern int register_android_text_StaticLayout(JNIEnv *env); extern int register_android_text_AndroidBidi(JNIEnv *env); extern int register_android_opengl_classes(JNIEnv *env); extern int register_android_server_NetworkManagementSocketTagger(JNIEnv* env); @@ -1105,6 +1106,7 @@ static const RegJNIRec gRegJNI[] = { REG_JNI(register_android_content_XmlBlock), REG_JNI(register_android_emoji_EmojiFactory), REG_JNI(register_android_text_AndroidCharacter), + REG_JNI(register_android_text_StaticLayout), REG_JNI(register_android_text_AndroidBidi), REG_JNI(register_android_view_InputDevice), REG_JNI(register_android_view_KeyCharacterMap), diff --git a/core/jni/android_text_StaticLayout.cpp b/core/jni/android_text_StaticLayout.cpp new file mode 100644 index 0000000..9e20d18 --- /dev/null +++ b/core/jni/android_text_StaticLayout.cpp @@ -0,0 +1,110 @@ +/* + * Copyright (C) 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#define LOG_TAG "StaticLayout" + +#include "ScopedIcuLocale.h" +#include "unicode/locid.h" +#include "unicode/brkiter.h" +#include "utils/misc.h" +#include "utils/Log.h" +#include "ScopedPrimitiveArray.h" +#include "JNIHelp.h" +#include <android_runtime/AndroidRuntime.h> +#include <vector> + +namespace android { + +class ScopedBreakIterator { + public: + ScopedBreakIterator(JNIEnv* env, BreakIterator* breakIterator, jcharArray inputText, + jint length) : mBreakIterator(breakIterator), mChars(env, inputText) { + UErrorCode status = U_ZERO_ERROR; + mUText = utext_openUChars(NULL, mChars.get(), length, &status); + if (mUText == NULL) { + return; + } + + mBreakIterator->setText(mUText, status); + } + + inline BreakIterator* operator->() { + return mBreakIterator; + } + + ~ScopedBreakIterator() { + utext_close(mUText); + delete mBreakIterator; + } + private: + BreakIterator* mBreakIterator; + ScopedCharArrayRO mChars; + UText* mUText; + + // disable copying and assignment + ScopedBreakIterator(const ScopedBreakIterator&); + void operator=(const ScopedBreakIterator&); +}; + +static jintArray nLineBreakOpportunities(JNIEnv* env, jclass, jstring javaLocaleName, + jcharArray inputText, jint length, + jintArray recycle) { + jintArray ret; + std::vector<jint> breaks; + + ScopedIcuLocale icuLocale(env, javaLocaleName); + if (icuLocale.valid()) { + UErrorCode status = U_ZERO_ERROR; + BreakIterator* it = BreakIterator::createLineInstance(icuLocale.locale(), status); + if (!U_SUCCESS(status) || it == NULL) { + if (it) { + delete it; + } + } else { + ScopedBreakIterator breakIterator(env, it, inputText, length); + for (int loc = breakIterator->first(); loc != BreakIterator::DONE; + loc = breakIterator->next()) { + breaks.push_back(loc); + } + } + } + + breaks.push_back(-1); // sentinel terminal value + + if (recycle != NULL && static_cast<size_t>(env->GetArrayLength(recycle)) >= breaks.size()) { + ret = recycle; + } else { + ret = env->NewIntArray(breaks.size()); + } + + if (ret != NULL) { + env->SetIntArrayRegion(ret, 0, breaks.size(), &breaks.front()); + } + + return ret; +} + +static JNINativeMethod gMethods[] = { + {"nLineBreakOpportunities", "(Ljava/lang/String;[CI[I)[I", (void*) nLineBreakOpportunities} +}; + +int register_android_text_StaticLayout(JNIEnv* env) +{ + return AndroidRuntime::registerNativeMethods(env, "android/text/StaticLayout", + gMethods, NELEM(gMethods)); +} + +} |