diff options
| -rw-r--r-- | core/java/android/text/StaticLayout.java | 36 | ||||
| -rw-r--r-- | core/jni/android_text_StaticLayout.cpp | 45 |
2 files changed, 44 insertions, 37 deletions
diff --git a/core/java/android/text/StaticLayout.java b/core/java/android/text/StaticLayout.java index 3303b54e462b..77e381a2d828 100644 --- a/core/java/android/text/StaticLayout.java +++ b/core/java/android/text/StaticLayout.java @@ -101,6 +101,7 @@ public class StaticLayout extends Layout { b.mBreakStrategy = Layout.BREAK_STRATEGY_SIMPLE; b.mHyphenationFrequency = Layout.HYPHENATION_FREQUENCY_NONE; b.mJustificationMode = Layout.JUSTIFICATION_MODE_NONE; + b.mLocales = null; b.mMeasuredText = MeasuredText.obtain(); return b; @@ -117,6 +118,7 @@ public class StaticLayout extends Layout { b.mMeasuredText = null; b.mLeftIndents = null; b.mRightIndents = null; + b.mLocales = null; nFinishBuilder(b.mNativePtr); sPool.release(b); } @@ -401,7 +403,6 @@ public class StaticLayout extends Layout { * future). * * Then, for each run within the paragraph: - * - setLocales (this must be done at least for the first run, optional afterwards) * - one of the following, depending on the type of run: * + addStyleRun (a text run, to be measured in native code) * + addMeasuredRun (a run already measured in Java, passed into native code) @@ -413,16 +414,21 @@ public class StaticLayout extends Layout { * After all paragraphs, call finish() to release expensive buffers. */ - private void setLocales(LocaleList locales) { + /* package */ float addStyleRun(TextPaint paint, int start, int end, boolean isRtl) { + final LocaleList locales = paint.getTextLocales(); + final String languageTags; + long[] hyphenators; if (!locales.equals(mLocales)) { - nSetLocales(mNativePtr, locales.toLanguageTags(), getHyphenators(locales)); - mLocales = locales; + languageTags = locales.toLanguageTags(); + hyphenators = getHyphenators(locales); + } else { + // passing null means keep current locale. + // TODO: move locale change detection to native. + languageTags = null; + hyphenators = null; } - } - - /* package */ float addStyleRun(TextPaint paint, int start, int end, boolean isRtl) { - setLocales(paint.getTextLocales()); - return nAddStyleRun(mNativePtr, paint.getNativeInstance(), start, end, isRtl); + return nAddStyleRun(mNativePtr, paint.getNativeInstance(), start, end, isRtl, + languageTags, hyphenators); } /* package */ void addMeasuredRun(int start, int end, float[] widths) { @@ -662,7 +668,6 @@ public class StaticLayout extends Layout { // store fontMetrics per span range // must be a multiple of 4 (and > 0) (store top, bottom, ascent, and descent per range) int[] fmCache = new int[4 * 4]; - b.setLocales(paint.getTextLocales()); mLineCount = 0; mEllipsized = false; @@ -1494,20 +1499,19 @@ public class StaticLayout extends Layout { /* package */ static native long nLoadHyphenator(ByteBuffer buf, int offset, int minPrefix, int minSuffix); - private static native void nSetLocales(long nativePtr, String locales, - long[] nativeHyphenators); - // Set up paragraph text and settings; done as one big method to minimize jni crossings private static native void nSetupParagraph( - @NonNull long nativePtr, @NonNull char[] text, @IntRange(from = 0) int length, + /* non zero */ long nativePtr, @NonNull char[] text, @IntRange(from = 0) int length, @FloatRange(from = 0.0f) float firstWidth, @IntRange(from = 0) int firstWidthLineCount, @FloatRange(from = 0.0f) float restWidth, @Nullable int[] variableTabStops, int defaultTabStop, @BreakStrategy int breakStrategy, @HyphenationFrequency int hyphenationFrequency, boolean isJustified, @Nullable int[] indents, @IntRange(from = 0) int indentsOffset); - private static native float nAddStyleRun(long nativePtr, long nativePaint, int start, int end, - boolean isRtl); + private static native float nAddStyleRun( + /* non zero */ long nativePtr, /* non zero */ long nativePaint, + @IntRange(from = 0) int start, @IntRange(from = 0) int end, boolean isRtl, + @Nullable String languageTags, @Nullable long[] hyphenators); private static native void nAddMeasuredRun(long nativePtr, int start, int end, float[] widths); diff --git a/core/jni/android_text_StaticLayout.cpp b/core/jni/android_text_StaticLayout.cpp index 7442fa2d62dc..6d861e84bf8e 100644 --- a/core/jni/android_text_StaticLayout.cpp +++ b/core/jni/android_text_StaticLayout.cpp @@ -187,24 +187,9 @@ static jlong nLoadHyphenator(JNIEnv* env, jclass, jobject buffer, jint offset, return reinterpret_cast<jlong>(hyphenator); } -static void nSetLocales(JNIEnv* env, jclass, jlong nativePtr, jstring javaLocaleNames, - jlongArray nativeHyphenators) { - minikin::LineBreaker* b = reinterpret_cast<minikin::LineBreaker*>(nativePtr); - - ScopedUtfChars localeNames(env, javaLocaleNames); - ScopedLongArrayRO hyphArr(env, nativeHyphenators); - const size_t numLocales = hyphArr.size(); - std::vector<minikin::Hyphenator*> hyphVec; - hyphVec.reserve(numLocales); - for (size_t i = 0; i < numLocales; i++) { - hyphVec.push_back(reinterpret_cast<minikin::Hyphenator*>(hyphArr[i])); - } - b->setLocales(localeNames.c_str(), hyphVec); -} - // Basically similar to Paint.getTextRunAdvances but with C++ interface static jfloat nAddStyleRun(JNIEnv* env, jclass, jlong nativePtr, jlong nativePaint, jint start, - jint end, jboolean isRtl) { + jint end, jboolean isRtl, jstring langTags, jlongArray hyphenators) { minikin::LineBreaker* b = reinterpret_cast<minikin::LineBreaker*>(nativePtr); Paint* paint = reinterpret_cast<Paint*>(nativePaint); const Typeface* typeface = paint->getAndroidTypeface(); @@ -212,8 +197,26 @@ static jfloat nAddStyleRun(JNIEnv* env, jclass, jlong nativePtr, jlong nativePai const Typeface* resolvedTypeface = Typeface::resolveDefault(typeface); minikin::FontStyle style = MinikinUtils::prepareMinikinPaint(&minikinPaint, paint, typeface); - return b->addStyleRun(&minikinPaint, resolvedTypeface->fFontCollection, style, start, end, - isRtl); + + std::vector<minikin::Hyphenator*> hyphVec; + const char* langTagStr; + if (langTags == nullptr) { + langTagStr = nullptr; // nullptr languageTag means keeping current locale + } else { + ScopedLongArrayRO hyphArr(env, hyphenators); + const size_t numLocales = hyphArr.size(); + hyphVec.reserve(numLocales); + for (size_t i = 0; i < numLocales; i++) { + hyphVec.push_back(reinterpret_cast<minikin::Hyphenator*>(hyphArr[i])); + } + langTagStr = env->GetStringUTFChars(langTags, nullptr); + } + float result = b->addStyleRun(&minikinPaint, resolvedTypeface->fFontCollection, style, start, + end, isRtl, langTagStr, hyphVec); + if (langTagStr != nullptr) { + env->ReleaseStringUTFChars(langTags, langTagStr); + } + return result; } // Accept width measurements for the run, passed in from Java @@ -221,7 +224,8 @@ static void nAddMeasuredRun(JNIEnv* env, jclass, jlong nativePtr, jint start, jint end, jfloatArray widths) { minikin::LineBreaker* b = reinterpret_cast<minikin::LineBreaker*>(nativePtr); env->GetFloatArrayRegion(widths, start, end - start, b->charWidths() + start); - b->addStyleRun(nullptr, nullptr, minikin::FontStyle{}, start, end, false); + b->addStyleRun(nullptr, nullptr, minikin::FontStyle{}, start, end, false, + nullptr /* keep current locale */, std::vector<minikin::Hyphenator*>()); } static void nAddReplacementRun(JNIEnv* env, jclass, jlong nativePtr, @@ -241,9 +245,8 @@ static const JNINativeMethod gMethods[] = { {"nFreeBuilder", "(J)V", (void*) nFreeBuilder}, {"nFinishBuilder", "(J)V", (void*) nFinishBuilder}, {"nLoadHyphenator", "(Ljava/nio/ByteBuffer;III)J", (void*) nLoadHyphenator}, - {"nSetLocales", "(JLjava/lang/String;[J)V", (void*) nSetLocales}, {"nSetupParagraph", "(J[CIFIF[IIIIZ[II)V", (void*) nSetupParagraph}, - {"nAddStyleRun", "(JJIIZ)F", (void*) nAddStyleRun}, + {"nAddStyleRun", "(JJIIZLjava/lang/String;[J)F", (void*) nAddStyleRun}, {"nAddMeasuredRun", "(JII[F)V", (void*) nAddMeasuredRun}, {"nAddReplacementRun", "(JIIF)V", (void*) nAddReplacementRun}, {"nGetWidths", "(J[F)V", (void*) nGetWidths}, |