Loading core/java/android/text/Layout.java +320 −154 File changed.Preview size limit exceeded, changes collapsed. Show changes core/java/android/text/StaticLayout.java +41 −18 Original line number Diff line number Diff line Loading @@ -23,6 +23,8 @@ import android.graphics.Paint; 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 Loading Loading @@ -146,7 +148,7 @@ extends Layout paraEnd++; int paraLen = paraEnd - paraStart; int firstWidthLineCount = 1; int firstWidthLineLimit = mLineCount + 1; int firstwidth = outerwidth; int restwidth = outerwidth; Loading @@ -159,10 +161,16 @@ extends Layout 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(); } } Loading Loading @@ -214,7 +222,9 @@ extends Layout 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) { Loading Loading @@ -252,8 +262,21 @@ extends Layout 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); Loading @@ -275,7 +298,7 @@ extends Layout bm.getHeight(); w += wid; tab = true; hasTabOrEmoji = true; j++; } else { w += widths[j - paraStart]; Loading Loading @@ -351,7 +374,7 @@ extends Layout 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, Loading Loading @@ -387,7 +410,7 @@ extends Layout 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, Loading @@ -403,7 +426,7 @@ extends Layout 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, Loading @@ -424,7 +447,7 @@ extends Layout fm.top, fm.bottom, v, spacingmult, spacingadd, chooseht, choosehtv, fm, tab, choosehtv, fm, hasTabOrEmoji, needMultiply, paraStart, chdirs, dir, easy, here + 1 == bufend, includepad, trackpad, Loading @@ -449,7 +472,7 @@ extends Layout fitascent = fitdescent = fittop = fitbottom = 0; okascent = okdescent = oktop = okbottom = 0; if (--firstWidthLineCount <= 0) { if (--firstWidthLineLimit <= 0) { width = restwidth; } } Loading @@ -473,7 +496,7 @@ extends Layout 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, Loading Loading @@ -613,7 +636,7 @@ extends Layout 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, Loading Loading @@ -700,7 +723,7 @@ extends Layout 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; Loading Loading @@ -914,7 +937,7 @@ extends Layout 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() Loading core/java/android/text/TextLine.java +8 −52 Original line number Diff line number Diff line Loading @@ -25,10 +25,10 @@ import android.graphics.RectF; import android.graphics.Paint.FontMetricsInt; import android.icu.text.ArabicShaping; import android.text.Layout.Directions; import android.text.Layout.TabStops; import android.text.style.CharacterStyle; import android.text.style.MetricAffectingSpan; import android.text.style.ReplacementSpan; import android.text.style.TabStopSpan; import android.util.Log; /** Loading @@ -51,7 +51,7 @@ class TextLine { private int mDir; private Directions mDirections; private boolean mHasTabs; private TabStopSpan[] mTabs; private TabStops mTabs; private char[] mChars; private boolean mCharsValid; Loading Loading @@ -117,11 +117,10 @@ class TextLine { * @param dir the paragraph direction of this line * @param directions the directions information of this line * @param hasTabs true if the line might contain tabs or emoji * @param spans array of paragraph-level spans, of which only TabStopSpans * are used. Can be null. * @param tabStops the tabStops. Can be null. */ void set(TextPaint paint, CharSequence text, int start, int limit, int dir, Directions directions, boolean hasTabs, Object[] spans) { Directions directions, boolean hasTabs, TabStops tabStops) { mPaint = paint; mText = text; mStart = start; Loading @@ -148,38 +147,8 @@ class TextLine { mChars = new char[ArrayUtils.idealCharArraySize(mLen)]; } TextUtils.getChars(text, start, limit, mChars, 0); if (hasTabs) { TabStopSpan[] tabs = mTabs; int tabLen = 0; if (mSpanned != null && spans == null) { TabStopSpan[] newTabs = mSpanned.getSpans(start, limit, TabStopSpan.class); if (tabs == null || tabs.length < newTabs.length) { tabs = newTabs; } else { for (int i = 0; i < newTabs.length; ++i) { tabs[i] = newTabs[i]; } } tabLen = newTabs.length; } else if (spans != null) { if (tabs == null || tabs.length < spans.length) { tabs = new TabStopSpan[spans.length]; } for (int i = 0; i < spans.length; ++i) { if (spans[i] instanceof TabStopSpan) { tabs[tabLen++] = (TabStopSpan) spans[i]; } } } if (tabs != null && tabLen < tabs.length){ tabs[tabLen] = null; } mTabs = tabs; } } mTabs = tabStops; } /** Loading Loading @@ -993,23 +962,10 @@ class TextLine { * @return the (unsigned) tab position after this offset */ float nextTab(float h) { float nh = Float.MAX_VALUE; boolean alltabs = false; if (mHasTabs && mTabs != null) { TabStopSpan[] tabs = mTabs; for (int i = 0; i < tabs.length && tabs[i] != null; ++i) { int where = tabs[i].getTabStop(); if (where < nh && where > h) { nh = where; if (mTabs != null) { return mTabs.nextTab(h); } } if (nh != Float.MAX_VALUE) { return nh; } } return ((int) ((h + TAB_INCREMENT) / TAB_INCREMENT)) * TAB_INCREMENT; return TabStops.nextDefaultStop(h, TAB_INCREMENT); } private static final int TAB_INCREMENT = 20; Loading core/java/android/text/method/Touch.java +7 −4 Original line number Diff line number Diff line Loading @@ -18,13 +18,12 @@ package android.text.method; import android.text.Layout; import android.text.NoCopySpan; import android.text.Layout.Alignment; import android.text.Spannable; import android.util.Log; import android.text.Layout.Alignment; import android.view.KeyEvent; import android.view.MotionEvent; import android.view.ViewConfiguration; import android.widget.TextView; import android.view.KeyEvent; public class Touch { private Touch() { } Loading @@ -45,6 +44,7 @@ public class Touch { int left = Integer.MAX_VALUE; int right = 0; Alignment a = null; boolean ltr = true; for (int i = top; i <= bottom; i++) { left = (int) Math.min(left, layout.getLineLeft(i)); Loading @@ -52,6 +52,7 @@ public class Touch { if (a == null) { a = layout.getParagraphAlignment(i); ltr = layout.getParagraphDirection(i) > 0; } } Loading @@ -59,10 +60,12 @@ public class Touch { int width = widget.getWidth(); int diff = 0; // align_opposite does NOT mean align_right, we need the paragraph // direction to resolve it to left or right if (right - left < width - padding) { if (a == Alignment.ALIGN_CENTER) { diff = (width - padding - (right - left)) / 2; } else if (a == Alignment.ALIGN_OPPOSITE) { } else if (ltr == (a == Alignment.ALIGN_OPPOSITE)) { diff = width - padding - (right - left); } } Loading core/java/android/widget/TextView.java +10 −4 Original line number Diff line number Diff line Loading @@ -4847,6 +4847,8 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener break; case Gravity.RIGHT: // Note, Layout resolves ALIGN_OPPOSITE to left or // right based on the paragraph direction. alignment = Layout.Alignment.ALIGN_OPPOSITE; break; Loading Loading @@ -5668,11 +5670,15 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener final int leftChar = mLayout.getOffsetForHorizontal(line, hs); final int rightChar = mLayout.getOffsetForHorizontal(line, hspace+hs); // line might contain bidirectional text final int lowChar = leftChar < rightChar ? leftChar : rightChar; final int highChar = leftChar > rightChar ? leftChar : rightChar; int newStart = start; if (newStart < leftChar) { newStart = leftChar; } else if (newStart > rightChar) { newStart = rightChar; if (newStart < lowChar) { newStart = lowChar; } else if (newStart > highChar) { newStart = highChar; } if (newStart != start) { Loading Loading
core/java/android/text/Layout.java +320 −154 File changed.Preview size limit exceeded, changes collapsed. Show changes
core/java/android/text/StaticLayout.java +41 −18 Original line number Diff line number Diff line Loading @@ -23,6 +23,8 @@ import android.graphics.Paint; 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 Loading Loading @@ -146,7 +148,7 @@ extends Layout paraEnd++; int paraLen = paraEnd - paraStart; int firstWidthLineCount = 1; int firstWidthLineLimit = mLineCount + 1; int firstwidth = outerwidth; int restwidth = outerwidth; Loading @@ -159,10 +161,16 @@ extends Layout 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(); } } Loading Loading @@ -214,7 +222,9 @@ extends Layout 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) { Loading Loading @@ -252,8 +262,21 @@ extends Layout 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); Loading @@ -275,7 +298,7 @@ extends Layout bm.getHeight(); w += wid; tab = true; hasTabOrEmoji = true; j++; } else { w += widths[j - paraStart]; Loading Loading @@ -351,7 +374,7 @@ extends Layout 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, Loading Loading @@ -387,7 +410,7 @@ extends Layout 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, Loading @@ -403,7 +426,7 @@ extends Layout 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, Loading @@ -424,7 +447,7 @@ extends Layout fm.top, fm.bottom, v, spacingmult, spacingadd, chooseht, choosehtv, fm, tab, choosehtv, fm, hasTabOrEmoji, needMultiply, paraStart, chdirs, dir, easy, here + 1 == bufend, includepad, trackpad, Loading @@ -449,7 +472,7 @@ extends Layout fitascent = fitdescent = fittop = fitbottom = 0; okascent = okdescent = oktop = okbottom = 0; if (--firstWidthLineCount <= 0) { if (--firstWidthLineLimit <= 0) { width = restwidth; } } Loading @@ -473,7 +496,7 @@ extends Layout 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, Loading Loading @@ -613,7 +636,7 @@ extends Layout 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, Loading Loading @@ -700,7 +723,7 @@ extends Layout 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; Loading Loading @@ -914,7 +937,7 @@ extends Layout 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() Loading
core/java/android/text/TextLine.java +8 −52 Original line number Diff line number Diff line Loading @@ -25,10 +25,10 @@ import android.graphics.RectF; import android.graphics.Paint.FontMetricsInt; import android.icu.text.ArabicShaping; import android.text.Layout.Directions; import android.text.Layout.TabStops; import android.text.style.CharacterStyle; import android.text.style.MetricAffectingSpan; import android.text.style.ReplacementSpan; import android.text.style.TabStopSpan; import android.util.Log; /** Loading @@ -51,7 +51,7 @@ class TextLine { private int mDir; private Directions mDirections; private boolean mHasTabs; private TabStopSpan[] mTabs; private TabStops mTabs; private char[] mChars; private boolean mCharsValid; Loading Loading @@ -117,11 +117,10 @@ class TextLine { * @param dir the paragraph direction of this line * @param directions the directions information of this line * @param hasTabs true if the line might contain tabs or emoji * @param spans array of paragraph-level spans, of which only TabStopSpans * are used. Can be null. * @param tabStops the tabStops. Can be null. */ void set(TextPaint paint, CharSequence text, int start, int limit, int dir, Directions directions, boolean hasTabs, Object[] spans) { Directions directions, boolean hasTabs, TabStops tabStops) { mPaint = paint; mText = text; mStart = start; Loading @@ -148,38 +147,8 @@ class TextLine { mChars = new char[ArrayUtils.idealCharArraySize(mLen)]; } TextUtils.getChars(text, start, limit, mChars, 0); if (hasTabs) { TabStopSpan[] tabs = mTabs; int tabLen = 0; if (mSpanned != null && spans == null) { TabStopSpan[] newTabs = mSpanned.getSpans(start, limit, TabStopSpan.class); if (tabs == null || tabs.length < newTabs.length) { tabs = newTabs; } else { for (int i = 0; i < newTabs.length; ++i) { tabs[i] = newTabs[i]; } } tabLen = newTabs.length; } else if (spans != null) { if (tabs == null || tabs.length < spans.length) { tabs = new TabStopSpan[spans.length]; } for (int i = 0; i < spans.length; ++i) { if (spans[i] instanceof TabStopSpan) { tabs[tabLen++] = (TabStopSpan) spans[i]; } } } if (tabs != null && tabLen < tabs.length){ tabs[tabLen] = null; } mTabs = tabs; } } mTabs = tabStops; } /** Loading Loading @@ -993,23 +962,10 @@ class TextLine { * @return the (unsigned) tab position after this offset */ float nextTab(float h) { float nh = Float.MAX_VALUE; boolean alltabs = false; if (mHasTabs && mTabs != null) { TabStopSpan[] tabs = mTabs; for (int i = 0; i < tabs.length && tabs[i] != null; ++i) { int where = tabs[i].getTabStop(); if (where < nh && where > h) { nh = where; if (mTabs != null) { return mTabs.nextTab(h); } } if (nh != Float.MAX_VALUE) { return nh; } } return ((int) ((h + TAB_INCREMENT) / TAB_INCREMENT)) * TAB_INCREMENT; return TabStops.nextDefaultStop(h, TAB_INCREMENT); } private static final int TAB_INCREMENT = 20; Loading
core/java/android/text/method/Touch.java +7 −4 Original line number Diff line number Diff line Loading @@ -18,13 +18,12 @@ package android.text.method; import android.text.Layout; import android.text.NoCopySpan; import android.text.Layout.Alignment; import android.text.Spannable; import android.util.Log; import android.text.Layout.Alignment; import android.view.KeyEvent; import android.view.MotionEvent; import android.view.ViewConfiguration; import android.widget.TextView; import android.view.KeyEvent; public class Touch { private Touch() { } Loading @@ -45,6 +44,7 @@ public class Touch { int left = Integer.MAX_VALUE; int right = 0; Alignment a = null; boolean ltr = true; for (int i = top; i <= bottom; i++) { left = (int) Math.min(left, layout.getLineLeft(i)); Loading @@ -52,6 +52,7 @@ public class Touch { if (a == null) { a = layout.getParagraphAlignment(i); ltr = layout.getParagraphDirection(i) > 0; } } Loading @@ -59,10 +60,12 @@ public class Touch { int width = widget.getWidth(); int diff = 0; // align_opposite does NOT mean align_right, we need the paragraph // direction to resolve it to left or right if (right - left < width - padding) { if (a == Alignment.ALIGN_CENTER) { diff = (width - padding - (right - left)) / 2; } else if (a == Alignment.ALIGN_OPPOSITE) { } else if (ltr == (a == Alignment.ALIGN_OPPOSITE)) { diff = width - padding - (right - left); } } Loading
core/java/android/widget/TextView.java +10 −4 Original line number Diff line number Diff line Loading @@ -4847,6 +4847,8 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener break; case Gravity.RIGHT: // Note, Layout resolves ALIGN_OPPOSITE to left or // right based on the paragraph direction. alignment = Layout.Alignment.ALIGN_OPPOSITE; break; Loading Loading @@ -5668,11 +5670,15 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener final int leftChar = mLayout.getOffsetForHorizontal(line, hs); final int rightChar = mLayout.getOffsetForHorizontal(line, hspace+hs); // line might contain bidirectional text final int lowChar = leftChar < rightChar ? leftChar : rightChar; final int highChar = leftChar > rightChar ? leftChar : rightChar; int newStart = start; if (newStart < leftChar) { newStart = leftChar; } else if (newStart > rightChar) { newStart = rightChar; if (newStart < lowChar) { newStart = lowChar; } else if (newStart > highChar) { newStart = highChar; } if (newStart != start) { Loading