Loading core/java/android/text/Layout.java +11 −0 Original line number Diff line number Diff line Loading @@ -633,6 +633,17 @@ public abstract class Layout { return getLineTop(getLineCount()); } /** * Return the total height of this layout. * * @param cap if true and max lines is set, returns the height of the layout at the max lines. * * @hide */ public int getHeight(boolean cap) { return getHeight(); } /** * Return the base alignment of this layout. */ Loading core/java/android/text/StaticLayout.java +64 −21 Original line number Diff line number Diff line Loading @@ -836,7 +836,7 @@ public class StaticLayout extends Layout { here = endPos; breakIndex++; if (mLineCount >= mMaximumVisibleLineCount) { if (mLineCount >= mMaximumVisibleLineCount && mEllipsized) { return; } } Loading Loading @@ -920,7 +920,25 @@ public class StaticLayout extends Layout { boolean firstLine = (j == 0); boolean currentLineIsTheLastVisibleOne = (j + 1 == mMaximumVisibleLineCount); boolean lastLine = currentLineIsTheLastVisibleOne || (end == bufEnd); if (ellipsize != null) { // If there is only one line, then do any type of ellipsis except when it is MARQUEE // if there are multiple lines, just allow END ellipsis on the last line boolean forceEllipsis = moreChars && (mLineCount + 1 == mMaximumVisibleLineCount); boolean doEllipsis = (((mMaximumVisibleLineCount == 1 && moreChars) || (firstLine && !moreChars)) && ellipsize != TextUtils.TruncateAt.MARQUEE) || (!firstLine && (currentLineIsTheLastVisibleOne || !moreChars) && ellipsize == TextUtils.TruncateAt.END); if (doEllipsis) { calculateEllipsis(start, end, widths, widthStart, ellipsisWidth, ellipsize, j, textWidth, paint, forceEllipsis); } } boolean lastLine = mEllipsized || (end == bufEnd); if (firstLine) { if (trackPad) { Loading @@ -944,7 +962,6 @@ public class StaticLayout extends Layout { } } if (needMultiply && !lastLine) { double ex = (below - above) * (spacingmult - 1) + spacingadd; if (ex >= 0) { Loading @@ -960,6 +977,15 @@ public class StaticLayout extends Layout { lines[off + TOP] = v; lines[off + DESCENT] = below + extra; // special case for non-ellipsized last visible line when maxLines is set // store the height as if it was ellipsized if (!mEllipsized && currentLineIsTheLastVisibleOne) { // below calculation as if it was the last line int maxLineBelow = includePad ? bottom : below; // similar to the calculation of v below, without the extra. mMaxLineHeight = v + (maxLineBelow - above); } v += (below - above) + extra; lines[off + mColumns + START] = end; lines[off + mColumns + TOP] = v; Loading @@ -981,23 +1007,6 @@ public class StaticLayout extends Layout { start - widthStart, end - start); } if (ellipsize != null) { // If there is only one line, then do any type of ellipsis except when it is MARQUEE // if there are multiple lines, just allow END ellipsis on the last line boolean forceEllipsis = moreChars && (mLineCount + 1 == mMaximumVisibleLineCount); boolean doEllipsis = (((mMaximumVisibleLineCount == 1 && moreChars) || (firstLine && !moreChars)) && ellipsize != TextUtils.TruncateAt.MARQUEE) || (!firstLine && (currentLineIsTheLastVisibleOne || !moreChars) && ellipsize == TextUtils.TruncateAt.END); if (doEllipsis) { calculateEllipsis(start, end, widths, widthStart, ellipsisWidth, ellipsize, j, textWidth, paint, forceEllipsis); } } mLineCount++; return v; } Loading Loading @@ -1105,7 +1114,7 @@ public class StaticLayout extends Layout { } } } mEllipsized = true; mLines[mColumns * line + ELLIPSIS_START] = ellipsisStart; mLines[mColumns * line + ELLIPSIS_COUNT] = ellipsisCount; } Loading Loading @@ -1243,6 +1252,25 @@ public class StaticLayout extends Layout { return mEllipsizedWidth; } /** * Return the total height of this layout. * * @param cap if true and max lines is set, returns the height of the layout at the max lines. * * @hide */ public int getHeight(boolean cap) { if (cap && mLineCount >= mMaximumVisibleLineCount && mMaxLineHeight == -1 && Log.isLoggable(TAG, Log.WARN)) { Log.w(TAG, "maxLineHeight should not be -1. " + " maxLines:" + mMaximumVisibleLineCount + " lineCount:" + mLineCount); } return cap && mLineCount >= mMaximumVisibleLineCount && mMaxLineHeight != -1 ? mMaxLineHeight : super.getHeight(); } private static native long nNewBuilder(); private static native void nFreeBuilder(long nativePtr); private static native void nFinishBuilder(long nativePtr); Loading Loading @@ -1281,6 +1309,21 @@ public class StaticLayout extends Layout { private int mColumns; private int mEllipsizedWidth; /** * Keeps track if ellipsize is applied to the text. */ private boolean mEllipsized; /** * If maxLines is set, ellipsize is not set, and the actual line count of text is greater than * or equal to maxLine, this variable holds the ideal visual height of the maxLine'th line * starting from the top of the layout. If maxLines is not set its value will be -1. * * The value is the same as getLineTop(maxLines) for ellipsized version where structurally no * more than maxLines is contained. */ private int mMaxLineHeight = -1; private static final int COLUMNS_NORMAL = 4; private static final int COLUMNS_ELLIPSIZE = 6; private static final int START = 0; Loading core/java/android/widget/TextView.java +15 −30 Original line number Diff line number Diff line Loading @@ -5157,7 +5157,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener * call {@link InputMethodManager#restartInput(View)}.</p> * @param hintLocales List of the languages that the user is supposed to switch to no matter * what input method subtype is currently used. Set {@code null} to clear the current "hint". * @see #getImeHIntLocales() * @see #getImeHintLocales() * @see android.view.inputmethod.EditorInfo#hintLocales */ public void setImeHintLocales(@Nullable LocaleList hintLocales) { Loading Loading @@ -7000,11 +7000,11 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener .setLineSpacing(mSpacingAdd, mSpacingMult) .setIncludePad(mIncludePad) .setBreakStrategy(mBreakStrategy) .setHyphenationFrequency(mHyphenationFrequency); .setHyphenationFrequency(mHyphenationFrequency) .setMaxLines(mMaxMode == LINES ? mMaximum : Integer.MAX_VALUE); if (shouldEllipsize) { builder.setEllipsize(mEllipsize) .setEllipsizedWidth(ellipsisWidth) .setMaxLines(mMaxMode == LINES ? mMaximum : Integer.MAX_VALUE); .setEllipsizedWidth(ellipsisWidth); } mHintLayout = builder.build(); } Loading Loading @@ -7091,11 +7091,11 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener .setLineSpacing(mSpacingAdd, mSpacingMult) .setIncludePad(mIncludePad) .setBreakStrategy(mBreakStrategy) .setHyphenationFrequency(mHyphenationFrequency); .setHyphenationFrequency(mHyphenationFrequency) .setMaxLines(mMaxMode == LINES ? mMaximum : Integer.MAX_VALUE); if (shouldEllipsize) { builder.setEllipsize(effectiveEllipsize) .setEllipsizedWidth(ellipsisWidth) .setMaxLines(mMaxMode == LINES ? mMaximum : Integer.MAX_VALUE); .setEllipsizedWidth(ellipsisWidth); } // TODO: explore always setting maxLines result = builder.build(); Loading Loading @@ -7367,41 +7367,26 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener return 0; } int linecount = layout.getLineCount(); int pad = getCompoundPaddingTop() + getCompoundPaddingBottom(); int desired = layout.getLineTop(linecount); final Drawables dr = mDrawables; if (dr != null) { desired = Math.max(desired, dr.mDrawableHeightLeft); desired = Math.max(desired, dr.mDrawableHeightRight); } desired += pad; if (mMaxMode == LINES) { /* * Don't cap the hint to a certain number of lines. * (Do cap it, though, if we have a maximum pixel height.) */ if (cap) { if (linecount > mMaximum) { desired = layout.getLineTop(mMaximum); int desired = layout.getHeight(cap); final Drawables dr = mDrawables; if (dr != null) { desired = Math.max(desired, dr.mDrawableHeightLeft); desired = Math.max(desired, dr.mDrawableHeightRight); } desired += pad; linecount = mMaximum; } } } else { desired += getCompoundPaddingTop() + getCompoundPaddingBottom(); if (mMaxMode != LINES) { desired = Math.min(desired, mMaximum); } if (mMinMode == LINES) { int linecount = layout.getLineCount(); if (linecount < mMinimum) { desired += getLineHeight() * (mMinimum - linecount); } Loading Loading
core/java/android/text/Layout.java +11 −0 Original line number Diff line number Diff line Loading @@ -633,6 +633,17 @@ public abstract class Layout { return getLineTop(getLineCount()); } /** * Return the total height of this layout. * * @param cap if true and max lines is set, returns the height of the layout at the max lines. * * @hide */ public int getHeight(boolean cap) { return getHeight(); } /** * Return the base alignment of this layout. */ Loading
core/java/android/text/StaticLayout.java +64 −21 Original line number Diff line number Diff line Loading @@ -836,7 +836,7 @@ public class StaticLayout extends Layout { here = endPos; breakIndex++; if (mLineCount >= mMaximumVisibleLineCount) { if (mLineCount >= mMaximumVisibleLineCount && mEllipsized) { return; } } Loading Loading @@ -920,7 +920,25 @@ public class StaticLayout extends Layout { boolean firstLine = (j == 0); boolean currentLineIsTheLastVisibleOne = (j + 1 == mMaximumVisibleLineCount); boolean lastLine = currentLineIsTheLastVisibleOne || (end == bufEnd); if (ellipsize != null) { // If there is only one line, then do any type of ellipsis except when it is MARQUEE // if there are multiple lines, just allow END ellipsis on the last line boolean forceEllipsis = moreChars && (mLineCount + 1 == mMaximumVisibleLineCount); boolean doEllipsis = (((mMaximumVisibleLineCount == 1 && moreChars) || (firstLine && !moreChars)) && ellipsize != TextUtils.TruncateAt.MARQUEE) || (!firstLine && (currentLineIsTheLastVisibleOne || !moreChars) && ellipsize == TextUtils.TruncateAt.END); if (doEllipsis) { calculateEllipsis(start, end, widths, widthStart, ellipsisWidth, ellipsize, j, textWidth, paint, forceEllipsis); } } boolean lastLine = mEllipsized || (end == bufEnd); if (firstLine) { if (trackPad) { Loading @@ -944,7 +962,6 @@ public class StaticLayout extends Layout { } } if (needMultiply && !lastLine) { double ex = (below - above) * (spacingmult - 1) + spacingadd; if (ex >= 0) { Loading @@ -960,6 +977,15 @@ public class StaticLayout extends Layout { lines[off + TOP] = v; lines[off + DESCENT] = below + extra; // special case for non-ellipsized last visible line when maxLines is set // store the height as if it was ellipsized if (!mEllipsized && currentLineIsTheLastVisibleOne) { // below calculation as if it was the last line int maxLineBelow = includePad ? bottom : below; // similar to the calculation of v below, without the extra. mMaxLineHeight = v + (maxLineBelow - above); } v += (below - above) + extra; lines[off + mColumns + START] = end; lines[off + mColumns + TOP] = v; Loading @@ -981,23 +1007,6 @@ public class StaticLayout extends Layout { start - widthStart, end - start); } if (ellipsize != null) { // If there is only one line, then do any type of ellipsis except when it is MARQUEE // if there are multiple lines, just allow END ellipsis on the last line boolean forceEllipsis = moreChars && (mLineCount + 1 == mMaximumVisibleLineCount); boolean doEllipsis = (((mMaximumVisibleLineCount == 1 && moreChars) || (firstLine && !moreChars)) && ellipsize != TextUtils.TruncateAt.MARQUEE) || (!firstLine && (currentLineIsTheLastVisibleOne || !moreChars) && ellipsize == TextUtils.TruncateAt.END); if (doEllipsis) { calculateEllipsis(start, end, widths, widthStart, ellipsisWidth, ellipsize, j, textWidth, paint, forceEllipsis); } } mLineCount++; return v; } Loading Loading @@ -1105,7 +1114,7 @@ public class StaticLayout extends Layout { } } } mEllipsized = true; mLines[mColumns * line + ELLIPSIS_START] = ellipsisStart; mLines[mColumns * line + ELLIPSIS_COUNT] = ellipsisCount; } Loading Loading @@ -1243,6 +1252,25 @@ public class StaticLayout extends Layout { return mEllipsizedWidth; } /** * Return the total height of this layout. * * @param cap if true and max lines is set, returns the height of the layout at the max lines. * * @hide */ public int getHeight(boolean cap) { if (cap && mLineCount >= mMaximumVisibleLineCount && mMaxLineHeight == -1 && Log.isLoggable(TAG, Log.WARN)) { Log.w(TAG, "maxLineHeight should not be -1. " + " maxLines:" + mMaximumVisibleLineCount + " lineCount:" + mLineCount); } return cap && mLineCount >= mMaximumVisibleLineCount && mMaxLineHeight != -1 ? mMaxLineHeight : super.getHeight(); } private static native long nNewBuilder(); private static native void nFreeBuilder(long nativePtr); private static native void nFinishBuilder(long nativePtr); Loading Loading @@ -1281,6 +1309,21 @@ public class StaticLayout extends Layout { private int mColumns; private int mEllipsizedWidth; /** * Keeps track if ellipsize is applied to the text. */ private boolean mEllipsized; /** * If maxLines is set, ellipsize is not set, and the actual line count of text is greater than * or equal to maxLine, this variable holds the ideal visual height of the maxLine'th line * starting from the top of the layout. If maxLines is not set its value will be -1. * * The value is the same as getLineTop(maxLines) for ellipsized version where structurally no * more than maxLines is contained. */ private int mMaxLineHeight = -1; private static final int COLUMNS_NORMAL = 4; private static final int COLUMNS_ELLIPSIZE = 6; private static final int START = 0; Loading
core/java/android/widget/TextView.java +15 −30 Original line number Diff line number Diff line Loading @@ -5157,7 +5157,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener * call {@link InputMethodManager#restartInput(View)}.</p> * @param hintLocales List of the languages that the user is supposed to switch to no matter * what input method subtype is currently used. Set {@code null} to clear the current "hint". * @see #getImeHIntLocales() * @see #getImeHintLocales() * @see android.view.inputmethod.EditorInfo#hintLocales */ public void setImeHintLocales(@Nullable LocaleList hintLocales) { Loading Loading @@ -7000,11 +7000,11 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener .setLineSpacing(mSpacingAdd, mSpacingMult) .setIncludePad(mIncludePad) .setBreakStrategy(mBreakStrategy) .setHyphenationFrequency(mHyphenationFrequency); .setHyphenationFrequency(mHyphenationFrequency) .setMaxLines(mMaxMode == LINES ? mMaximum : Integer.MAX_VALUE); if (shouldEllipsize) { builder.setEllipsize(mEllipsize) .setEllipsizedWidth(ellipsisWidth) .setMaxLines(mMaxMode == LINES ? mMaximum : Integer.MAX_VALUE); .setEllipsizedWidth(ellipsisWidth); } mHintLayout = builder.build(); } Loading Loading @@ -7091,11 +7091,11 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener .setLineSpacing(mSpacingAdd, mSpacingMult) .setIncludePad(mIncludePad) .setBreakStrategy(mBreakStrategy) .setHyphenationFrequency(mHyphenationFrequency); .setHyphenationFrequency(mHyphenationFrequency) .setMaxLines(mMaxMode == LINES ? mMaximum : Integer.MAX_VALUE); if (shouldEllipsize) { builder.setEllipsize(effectiveEllipsize) .setEllipsizedWidth(ellipsisWidth) .setMaxLines(mMaxMode == LINES ? mMaximum : Integer.MAX_VALUE); .setEllipsizedWidth(ellipsisWidth); } // TODO: explore always setting maxLines result = builder.build(); Loading Loading @@ -7367,41 +7367,26 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener return 0; } int linecount = layout.getLineCount(); int pad = getCompoundPaddingTop() + getCompoundPaddingBottom(); int desired = layout.getLineTop(linecount); final Drawables dr = mDrawables; if (dr != null) { desired = Math.max(desired, dr.mDrawableHeightLeft); desired = Math.max(desired, dr.mDrawableHeightRight); } desired += pad; if (mMaxMode == LINES) { /* * Don't cap the hint to a certain number of lines. * (Do cap it, though, if we have a maximum pixel height.) */ if (cap) { if (linecount > mMaximum) { desired = layout.getLineTop(mMaximum); int desired = layout.getHeight(cap); final Drawables dr = mDrawables; if (dr != null) { desired = Math.max(desired, dr.mDrawableHeightLeft); desired = Math.max(desired, dr.mDrawableHeightRight); } desired += pad; linecount = mMaximum; } } } else { desired += getCompoundPaddingTop() + getCompoundPaddingBottom(); if (mMaxMode != LINES) { desired = Math.min(desired, mMaximum); } if (mMinMode == LINES) { int linecount = layout.getLineCount(); if (linecount < mMinimum) { desired += getLineHeight() * (mMinimum - linecount); } Loading