summaryrefslogtreecommitdiff
path: root/android/text/StaticLayout.java
diff options
context:
space:
mode:
Diffstat (limited to 'android/text/StaticLayout.java')
-rw-r--r--android/text/StaticLayout.java74
1 files changed, 56 insertions, 18 deletions
diff --git a/android/text/StaticLayout.java b/android/text/StaticLayout.java
index 5c60188d..961cd8ee 100644
--- a/android/text/StaticLayout.java
+++ b/android/text/StaticLayout.java
@@ -21,18 +21,21 @@ import android.annotation.IntRange;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.graphics.Paint;
+import android.os.LocaleList;
import android.text.style.LeadingMarginSpan;
import android.text.style.LeadingMarginSpan.LeadingMarginSpan2;
import android.text.style.LineHeightSpan;
import android.text.style.MetricAffectingSpan;
import android.text.style.TabStopSpan;
import android.util.Log;
+import android.util.Pair;
import android.util.Pools.SynchronizedPool;
import com.android.internal.util.ArrayUtils;
import com.android.internal.util.GrowingArrayUtils;
import java.util.Arrays;
+import java.util.Locale;
/**
* StaticLayout is a Layout for text that will not be edited after it
@@ -98,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;
@@ -114,6 +118,7 @@ public class StaticLayout extends Layout {
b.mMeasuredText = null;
b.mLeftIndents = null;
b.mRightIndents = null;
+ b.mLocales = null;
b.mLeftPaddings = null;
b.mRightPaddings = null;
nFinishBuilder(b.mNativePtr);
@@ -404,6 +409,17 @@ public class StaticLayout extends Layout {
return this;
}
+ @NonNull
+ private long[] getHyphenators(@NonNull LocaleList locales) {
+ final int length = locales.size();
+ final long[] result = new long[length];
+ for (int i = 0; i < length; i++) {
+ final Locale locale = locales.get(i);
+ result[i] = Hyphenator.get(locale).getNativePtr();
+ }
+ return result;
+ }
+
/**
* Measurement and break iteration is done in native code. The protocol for using
* the native code is as follows.
@@ -417,17 +433,35 @@ public class StaticLayout extends Layout {
* + addStyleRun (a text run, to be measured in native code)
* + addReplacementRun (a replacement run, width is given)
*
+ * After measurement, nGetWidths() is valid if the widths are needed (eg for ellipsis).
* Run nComputeLineBreaks() to obtain line breaks for the paragraph.
*
* After all paragraphs, call finish() to release expensive buffers.
*/
+ private Pair<String, long[]> getLocaleAndHyphenatorIfChanged(TextPaint paint) {
+ final LocaleList locales = paint.getTextLocales();
+ final String languageTags;
+ long[] hyphenators;
+ if (!locales.equals(mLocales)) {
+ mLocales = locales;
+ return new Pair(locales.toLanguageTags(), getHyphenators(locales));
+ } else {
+ // passing null means keep current locale.
+ // TODO: move locale change detection to native.
+ return new Pair(null, null);
+ }
+ }
+
/* package */ void addStyleRun(TextPaint paint, int start, int end, boolean isRtl) {
- nAddStyleRun(mNativePtr, paint.getNativeInstance(), start, end, isRtl);
+ Pair<String, long[]> locHyph = getLocaleAndHyphenatorIfChanged(paint);
+ nAddStyleRun(mNativePtr, paint.getNativeInstance(), start, end, isRtl, locHyph.first,
+ locHyph.second);
}
/* package */ void addReplacementRun(TextPaint paint, int start, int end, float width) {
- nAddReplacementRun(mNativePtr, paint.getNativeInstance(), start, end, width);
+ Pair<String, long[]> locHyph = getLocaleAndHyphenatorIfChanged(paint);
+ nAddReplacementRun(mNativePtr, start, end, width, locHyph.first, locHyph.second);
}
/**
@@ -485,7 +519,9 @@ public class StaticLayout extends Layout {
// This will go away and be subsumed by native builder code
private MeasuredText mMeasuredText;
- private static final SynchronizedPool<Builder> sPool = new SynchronizedPool<>(3);
+ private LocaleList mLocales;
+
+ private static final SynchronizedPool<Builder> sPool = new SynchronizedPool<Builder>(3);
}
public StaticLayout(CharSequence source, TextPaint paint,
@@ -774,6 +810,9 @@ public class StaticLayout extends Layout {
}
}
+ // TODO: Move locale tracking code to native.
+ b.mLocales = null; // Reset the locale tracking.
+
nSetupParagraph(b.mNativePtr, chs, paraEnd - paraStart,
firstWidth, firstWidthLineCount, restWidth,
variableTabStops, TAB_INCREMENT, b.mBreakStrategy, b.mHyphenationFrequency,
@@ -827,9 +866,10 @@ public class StaticLayout extends Layout {
spanEndCacheCount++;
}
+ nGetWidths(b.mNativePtr, widths);
int breakCount = nComputeLineBreaks(b.mNativePtr, lineBreaks, lineBreaks.breaks,
lineBreaks.widths, lineBreaks.ascents, lineBreaks.descents, lineBreaks.flags,
- lineBreaks.breaks.length, widths);
+ lineBreaks.breaks.length);
final int[] breaks = lineBreaks.breaks;
final float[] lineWidths = lineBreaks.widths;
@@ -907,10 +947,10 @@ public class StaticLayout extends Layout {
boolean moreChars = (endPos < bufEnd);
final int ascent = fallbackLineSpacing
- ? Math.min(fmAscent, Math.round(ascents[breakIndex]))
+ ? Math.min(fmAscent, (int) Math.round(ascents[breakIndex]))
: fmAscent;
final int descent = fallbackLineSpacing
- ? Math.max(fmDescent, Math.round(descents[breakIndex]))
+ ? Math.max(fmDescent, (int) Math.round(descents[breakIndex]))
: fmDescent;
v = out(source, here, endPos,
ascent, descent, fmTop, fmBottom,
@@ -1137,7 +1177,7 @@ public class StaticLayout extends Layout {
mWorkPaint.set(paint);
do {
final float ellipsizedWidth = guessEllipsis(text, lineStart, lineEnd, widths,
- widthStart, tempAvail, where, line, mWorkPaint, forceEllipsis, dir);
+ widthStart, tempAvail, where, line, textWidth, mWorkPaint, forceEllipsis, dir);
if (ellipsizedWidth <= avail) {
lineFits = true;
} else {
@@ -1167,7 +1207,7 @@ public class StaticLayout extends Layout {
// This method temporarily modifies the TextPaint passed to it, so the TextPaint passed to it
// should not be accessed while the method is running.
private float guessEllipsis(CharSequence text, int lineStart, int lineEnd, float[] widths,
- int widthStart, float avail, TextUtils.TruncateAt where, int line,
+ int widthStart, float avail, TextUtils.TruncateAt where, int line, float textWidth,
TextPaint paint, boolean forceEllipsis, int dir) {
final int savedHyphenEdit = paint.getHyphenEdit();
paint.setHyphenEdit(0);
@@ -1501,28 +1541,26 @@ public class StaticLayout extends Layout {
@Nullable int[] indents, @Nullable int[] leftPaddings, @Nullable int[] rightPaddings,
@IntRange(from = 0) int indentsOffset);
- // TODO: Make this method CriticalNative once native code defers doing layouts.
private static native void nAddStyleRun(
/* non-zero */ long nativePtr, /* non-zero */ long nativePaint,
- @IntRange(from = 0) int start, @IntRange(from = 0) int end, boolean isRtl);
+ @IntRange(from = 0) int start, @IntRange(from = 0) int end, boolean isRtl,
+ @Nullable String languageTags, @Nullable long[] hyphenators);
- // TODO: Make this method CriticalNative once native code defers doing layouts.
- private static native void nAddReplacementRun(
- /* non-zero */ long nativePtr, /* non-zero */ long nativePaint,
+ private static native void nAddReplacementRun(/* non-zero */ long nativePtr,
@IntRange(from = 0) int start, @IntRange(from = 0) int end,
- @FloatRange(from = 0.0f) float width);
+ @FloatRange(from = 0.0f) float width, @Nullable String languageTags,
+ @Nullable long[] hyphenators);
+
+ private static native void nGetWidths(long nativePtr, float[] widths);
// populates LineBreaks and returns the number of breaks found
//
// the arrays inside the LineBreaks objects are passed in as well
// to reduce the number of JNI calls in the common case where the
// arrays do not have to be resized
- // The individual character widths will be returned in charWidths. The length of charWidths must
- // be at least the length of the text.
private static native int nComputeLineBreaks(long nativePtr, LineBreaks recycle,
int[] recycleBreaks, float[] recycleWidths, float[] recycleAscents,
- float[] recycleDescents, int[] recycleFlags, int recycleLength,
- float[] charWidths);
+ float[] recycleDescents, int[] recycleFlags, int recycleLength);
private int mLineCount;
private int mTopPadding, mBottomPadding;