Fix alignment issues with RTL paragraphs.
Also remove unused debugging code that depends on junit.
Remove trailing whitespace in changed code.
Change-Id: Ie02d1b8220c599a672ee6e91af0fba634e0f620c
diff --git a/core/java/android/text/StaticLayout.java b/core/java/android/text/StaticLayout.java
index 3d7e35b..1646b9e 100644
--- a/core/java/android/text/StaticLayout.java
+++ b/core/java/android/text/StaticLayout.java
@@ -23,6 +23,8 @@
import android.text.style.LeadingMarginSpan;
import android.text.style.LineHeightSpan;
import android.text.style.MetricAffectingSpan;
+import android.text.style.TabStopSpan;
+import android.text.style.LeadingMarginSpan.LeadingMarginSpan2;
/**
* StaticLayout is a Layout for text that will not be edited after it
@@ -146,7 +148,7 @@
paraEnd++;
int paraLen = paraEnd - paraStart;
- int firstWidthLineCount = 1;
+ int firstWidthLineLimit = mLineCount + 1;
int firstwidth = outerwidth;
int restwidth = outerwidth;
@@ -159,10 +161,16 @@
LeadingMarginSpan lms = sp[i];
firstwidth -= sp[i].getLeadingMargin(true);
restwidth -= sp[i].getLeadingMargin(false);
- if (lms instanceof LeadingMarginSpan.LeadingMarginSpan2) {
- firstWidthLineCount =
- ((LeadingMarginSpan.LeadingMarginSpan2)lms)
- .getLeadingMarginLineCount();
+
+ // LeadingMarginSpan2 is odd. The count affects all
+ // leading margin spans, not just this particular one,
+ // and start from the top of the span, not the top of the
+ // paragraph.
+ if (lms instanceof LeadingMarginSpan2) {
+ LeadingMarginSpan2 lms2 = (LeadingMarginSpan2) lms;
+ int lmsFirstLine = getLineForOffset(spanned.getSpanStart(lms2));
+ firstWidthLineLimit = lmsFirstLine +
+ lms2.getLeadingMarginLineCount();
}
}
@@ -214,7 +222,9 @@
float fitwidth = w;
int fitascent = 0, fitdescent = 0, fittop = 0, fitbottom = 0;
- boolean tab = false;
+ boolean hasTabOrEmoji = false;
+ boolean hasTab = false;
+ TabStops tabStops = null;
for (int spanStart = paraStart, spanEnd = spanStart, nextSpanStart;
spanStart < paraEnd; spanStart = nextSpanStart) {
@@ -252,8 +262,21 @@
if (c == '\n') {
;
} else if (c == '\t') {
- w = Layout.nextTab(sub, paraStart, paraEnd, w, null);
- tab = true;
+ if (hasTab == false) {
+ hasTab = true;
+ hasTabOrEmoji = true;
+ // First tab this para, check for tabstops
+ TabStopSpan[] spans = spanned.getSpans(paraStart,
+ paraEnd, TabStopSpan.class);
+ if (spans.length > 0) {
+ tabStops = new TabStops(TAB_INCREMENT, spans);
+ }
+ }
+ if (tabStops != null) {
+ w = tabStops.nextTab(w);
+ } else {
+ w = TabStops.nextDefaultStop(w, TAB_INCREMENT);
+ }
} else if (c >= 0xD800 && c <= 0xDFFF && j + 1 < spanEnd) {
int emoji = Character.codePointAt(chs, j - paraStart);
@@ -275,7 +298,7 @@
bm.getHeight();
w += wid;
- tab = true;
+ hasTabOrEmoji = true;
j++;
} else {
w += widths[j - paraStart];
@@ -351,7 +374,7 @@
okascent, okdescent, oktop, okbottom,
v,
spacingmult, spacingadd, chooseht,
- choosehtv, fm, tab,
+ choosehtv, fm, hasTabOrEmoji,
needMultiply, paraStart, chdirs, dir, easy,
ok == bufend, includepad, trackpad,
chs, widths, here - paraStart,
@@ -387,7 +410,7 @@
okascent, okdescent, oktop, okbottom,
v,
spacingmult, spacingadd, chooseht,
- choosehtv, fm, tab,
+ choosehtv, fm, hasTabOrEmoji,
needMultiply, paraStart, chdirs, dir, easy,
ok == bufend, includepad, trackpad,
chs, widths, here - paraStart,
@@ -403,7 +426,7 @@
fittop, fitbottom,
v,
spacingmult, spacingadd, chooseht,
- choosehtv, fm, tab,
+ choosehtv, fm, hasTabOrEmoji,
needMultiply, paraStart, chdirs, dir, easy,
fit == bufend, includepad, trackpad,
chs, widths, here - paraStart,
@@ -424,7 +447,7 @@
fm.top, fm.bottom,
v,
spacingmult, spacingadd, chooseht,
- choosehtv, fm, tab,
+ choosehtv, fm, hasTabOrEmoji,
needMultiply, paraStart, chdirs, dir, easy,
here + 1 == bufend, includepad,
trackpad,
@@ -449,7 +472,7 @@
fitascent = fitdescent = fittop = fitbottom = 0;
okascent = okdescent = oktop = okbottom = 0;
- if (--firstWidthLineCount <= 0) {
+ if (--firstWidthLineLimit <= 0) {
width = restwidth;
}
}
@@ -473,7 +496,7 @@
fittop, fitbottom,
v,
spacingmult, spacingadd, chooseht,
- choosehtv, fm, tab,
+ choosehtv, fm, hasTabOrEmoji,
needMultiply, paraStart, chdirs, dir, easy,
paraEnd == bufend, includepad, trackpad,
chs, widths, here - paraStart,
@@ -613,7 +636,7 @@
int above, int below, int top, int bottom, int v,
float spacingmult, float spacingadd,
LineHeightSpan[] chooseht, int[] choosehtv,
- Paint.FontMetricsInt fm, boolean tab,
+ Paint.FontMetricsInt fm, boolean hasTabOrEmoji,
boolean needMultiply, int pstart, byte[] chdirs,
int dir, boolean easy, boolean last,
boolean includepad, boolean trackpad,
@@ -700,7 +723,7 @@
lines[off + mColumns + START] = end;
lines[off + mColumns + TOP] = v;
- if (tab)
+ if (hasTabOrEmoji)
lines[off + TAB] |= TAB_MASK;
lines[off + DIR] |= dir << DIR_SHIFT;
@@ -914,7 +937,7 @@
private static final int DIR_SHIFT = 30;
private static final int TAB_MASK = 0x20000000;
- private static final char FIRST_RIGHT_TO_LEFT = '\u0590';
+ private static final int TAB_INCREMENT = 20; // same as Layout, but that's private
/*
* This is reused across calls to generate()