Loading core/java/android/text/StaticLayout.java +20 −16 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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); } Loading Loading @@ -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) Loading @@ -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) { Loading Loading @@ -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; Loading Loading @@ -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); Loading core/jni/android_text_StaticLayout.cpp +24 −21 Original line number Diff line number Diff line Loading @@ -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(); Loading @@ -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 Loading @@ -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, Loading @@ -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}, Loading Loading
core/java/android/text/StaticLayout.java +20 −16 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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); } Loading Loading @@ -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) Loading @@ -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) { Loading Loading @@ -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; Loading Loading @@ -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); Loading
core/jni/android_text_StaticLayout.cpp +24 −21 Original line number Diff line number Diff line Loading @@ -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(); Loading @@ -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 Loading @@ -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, Loading @@ -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}, Loading