summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/java/android/text/StaticLayout.java36
-rw-r--r--core/jni/android_text_StaticLayout.cpp45
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},