Merge "Stop creating PrecomputedText in StaticLayout" into pi-dev

This commit is contained in:
TreeHugger Robot
2018-03-21 04:28:54 +00:00
committed by Android (Google) Code Review
4 changed files with 77 additions and 62 deletions

View File

@@ -119,8 +119,12 @@ public class PrecomputedTextMemoryUsageTest {
// Report median of randomly generated PrecomputedText.
for (int i = 0; i < TRIAL_COUNT; ++i) {
CharSequence cs = mTextUtil.nextRandomParagraph(WORD_LENGTH, NO_STYLE_TEXT);
memories[i] = PrecomputedText.createWidthOnly(cs, param, 0, cs.length())
.getMemoryUsage();
PrecomputedText.ParagraphInfo[] paragraphInfo =
PrecomputedText.createMeasuredParagraphs(cs, param, 0, cs.length(), false);
memories[i] = 0;
for (PrecomputedText.ParagraphInfo info : paragraphInfo) {
memories[i] += info.measured.getMemoryUsage();
}
}
reportMemoryUsage(median(memories), "MemoryUsage_NoHyphenation_WidthOnly");
}
@@ -136,8 +140,12 @@ public class PrecomputedTextMemoryUsageTest {
// Report median of randomly generated PrecomputedText.
for (int i = 0; i < TRIAL_COUNT; ++i) {
CharSequence cs = mTextUtil.nextRandomParagraph(WORD_LENGTH, NO_STYLE_TEXT);
memories[i] = PrecomputedText.createWidthOnly(cs, param, 0, cs.length())
.getMemoryUsage();
PrecomputedText.ParagraphInfo[] paragraphInfo =
PrecomputedText.createMeasuredParagraphs(cs, param, 0, cs.length(), false);
memories[i] = 0;
for (PrecomputedText.ParagraphInfo info : paragraphInfo) {
memories[i] += info.measured.getMemoryUsage();
}
}
reportMemoryUsage(median(memories), "MemoryUsage_Hyphenation_WidthOnly");
}

View File

@@ -675,7 +675,7 @@ public class MeasuredParagraph {
/**
* This only works if the MeasuredParagraph is computed with buildForStaticLayout.
*/
@IntRange(from = 0) int getMemoryUsage() {
public @IntRange(from = 0) int getMemoryUsage() {
return nGetMemoryUsage(mNativePtr);
}

View File

@@ -19,7 +19,6 @@ package android.text;
import android.annotation.IntRange;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.util.IntArray;
import com.android.internal.util.Preconditions;
@@ -267,6 +266,22 @@ public class PrecomputedText implements Spanned {
}
};
/** @hide */
public static class ParagraphInfo {
public final @IntRange(from = 0) int paragraphEnd;
public final @NonNull MeasuredParagraph measured;
/**
* @param paraEnd the end offset of this paragraph
* @param measured a measured paragraph
*/
public ParagraphInfo(@IntRange(from = 0) int paraEnd, @NonNull MeasuredParagraph measured) {
this.paragraphEnd = paraEnd;
this.measured = measured;
}
};
// The original text.
private final @NonNull SpannedString mText;
@@ -278,11 +293,8 @@ public class PrecomputedText implements Spanned {
private final @NonNull Params mParams;
// The measured paragraph texts.
private final @NonNull MeasuredParagraph[] mMeasuredParagraphs;
// The sorted paragraph end offsets.
private final @NonNull int[] mParagraphBreakPoints;
// The list of measured paragraph info.
private final @NonNull ParagraphInfo[] mParagraphInfo;
/**
* Create a new {@link PrecomputedText} which will pre-compute text measurement and glyph
@@ -293,28 +305,25 @@ public class PrecomputedText implements Spanned {
* </p>
*
* @param text the text to be measured
* @param param parameters that define how text will be precomputed
* @param params parameters that define how text will be precomputed
* @return A {@link PrecomputedText}
*/
public static PrecomputedText create(@NonNull CharSequence text, @NonNull Params param) {
return createInternal(text, param, 0, text.length(), true /* compute full Layout */);
public static PrecomputedText create(@NonNull CharSequence text, @NonNull Params params) {
ParagraphInfo[] paraInfo = createMeasuredParagraphs(
text, params, 0, text.length(), true /* computeLayout */);
return new PrecomputedText(text, 0, text.length(), params, paraInfo);
}
/** @hide */
public static PrecomputedText createWidthOnly(@NonNull CharSequence text, @NonNull Params param,
@IntRange(from = 0) int start, @IntRange(from = 0) int end) {
return createInternal(text, param, start, end, false /* compute width only */);
}
private static PrecomputedText createInternal(@NonNull CharSequence text, @NonNull Params param,
public static ParagraphInfo[] createMeasuredParagraphs(
@NonNull CharSequence text, @NonNull Params params,
@IntRange(from = 0) int start, @IntRange(from = 0) int end, boolean computeLayout) {
Preconditions.checkNotNull(text);
Preconditions.checkNotNull(param);
final boolean needHyphenation = param.getBreakStrategy() != Layout.BREAK_STRATEGY_SIMPLE
&& param.getHyphenationFrequency() != Layout.HYPHENATION_FREQUENCY_NONE;
ArrayList<ParagraphInfo> result = new ArrayList<>();
final IntArray paragraphEnds = new IntArray();
final ArrayList<MeasuredParagraph> measuredTexts = new ArrayList<>();
Preconditions.checkNotNull(text);
Preconditions.checkNotNull(params);
final boolean needHyphenation = params.getBreakStrategy() != Layout.BREAK_STRATEGY_SIMPLE
&& params.getHyphenationFrequency() != Layout.HYPHENATION_FREQUENCY_NONE;
int paraEnd = 0;
for (int paraStart = start; paraStart < end; paraStart = paraEnd) {
@@ -327,27 +336,22 @@ public class PrecomputedText implements Spanned {
paraEnd++; // Includes LINE_FEED(U+000A) to the prev paragraph.
}
paragraphEnds.add(paraEnd);
measuredTexts.add(MeasuredParagraph.buildForStaticLayout(
param.getTextPaint(), text, paraStart, paraEnd, param.getTextDirection(),
needHyphenation, computeLayout, null /* no recycle */));
result.add(new ParagraphInfo(paraEnd, MeasuredParagraph.buildForStaticLayout(
params.getTextPaint(), text, paraStart, paraEnd, params.getTextDirection(),
needHyphenation, computeLayout, null /* no recycle */)));
}
return new PrecomputedText(text, start, end, param,
measuredTexts.toArray(new MeasuredParagraph[measuredTexts.size()]),
paragraphEnds.toArray());
return result.toArray(new ParagraphInfo[result.size()]);
}
// Use PrecomputedText.create instead.
private PrecomputedText(@NonNull CharSequence text, @IntRange(from = 0) int start,
@IntRange(from = 0) int end, @NonNull Params param,
@NonNull MeasuredParagraph[] measuredTexts, @NonNull int[] paragraphBreakPoints) {
@IntRange(from = 0) int end, @NonNull Params params,
@NonNull ParagraphInfo[] paraInfo) {
mText = new SpannedString(text);
mStart = start;
mEnd = end;
mParams = param;
mMeasuredParagraphs = measuredTexts;
mParagraphBreakPoints = paragraphBreakPoints;
mParams = params;
mParagraphInfo = paraInfo;
}
/**
@@ -384,7 +388,7 @@ public class PrecomputedText implements Spanned {
* Returns the count of paragraphs.
*/
public @IntRange(from = 0) int getParagraphCount() {
return mParagraphBreakPoints.length;
return mParagraphInfo.length;
}
/**
@@ -392,7 +396,7 @@ public class PrecomputedText implements Spanned {
*/
public @IntRange(from = 0) int getParagraphStart(@IntRange(from = 0) int paraIndex) {
Preconditions.checkArgumentInRange(paraIndex, 0, getParagraphCount(), "paraIndex");
return paraIndex == 0 ? mStart : mParagraphBreakPoints[paraIndex - 1];
return paraIndex == 0 ? mStart : getParagraphEnd(paraIndex - 1);
}
/**
@@ -400,12 +404,17 @@ public class PrecomputedText implements Spanned {
*/
public @IntRange(from = 0) int getParagraphEnd(@IntRange(from = 0) int paraIndex) {
Preconditions.checkArgumentInRange(paraIndex, 0, getParagraphCount(), "paraIndex");
return mParagraphBreakPoints[paraIndex];
return mParagraphInfo[paraIndex].paragraphEnd;
}
/** @hide */
public @NonNull MeasuredParagraph getMeasuredParagraph(@IntRange(from = 0) int paraIndex) {
return mMeasuredParagraphs[paraIndex];
return mParagraphInfo[paraIndex].measured;
}
/** @hide */
public @NonNull ParagraphInfo[] getParagraphInfo() {
return mParagraphInfo;
}
/**
@@ -425,13 +434,13 @@ public class PrecomputedText implements Spanned {
public int findParaIndex(@IntRange(from = 0) int pos) {
// TODO: Maybe good to remove paragraph concept from PrecomputedText and add substring
// layout support to StaticLayout.
for (int i = 0; i < mParagraphBreakPoints.length; ++i) {
if (pos < mParagraphBreakPoints[i]) {
for (int i = 0; i < mParagraphInfo.length; ++i) {
if (pos < mParagraphInfo[i].paragraphEnd) {
return i;
}
}
throw new IndexOutOfBoundsException(
"pos must be less than " + mParagraphBreakPoints[mParagraphBreakPoints.length - 1]
"pos must be less than " + mParagraphInfo[mParagraphInfo.length - 1].paragraphEnd
+ ", gave " + pos);
}

View File

@@ -651,31 +651,29 @@ public class StaticLayout extends Layout {
b.mJustificationMode != Layout.JUSTIFICATION_MODE_NONE,
indents, mLeftPaddings, mRightPaddings);
PrecomputedText measured = null;
final Spanned spanned;
PrecomputedText.ParagraphInfo[] paragraphInfo = null;
final Spanned spanned = (source instanceof Spanned) ? (Spanned) source : null;
if (source instanceof PrecomputedText) {
measured = (PrecomputedText) source;
if (!measured.canUseMeasuredResult(bufStart, bufEnd, textDir, paint, b.mBreakStrategy,
b.mHyphenationFrequency)) {
PrecomputedText precomputed = (PrecomputedText) source;
if (precomputed.canUseMeasuredResult(bufStart, bufEnd, textDir, paint,
b.mBreakStrategy, b.mHyphenationFrequency)) {
// Some parameters are different from the ones when measured text is created.
measured = null;
paragraphInfo = precomputed.getParagraphInfo();
}
}
if (measured == null) {
if (paragraphInfo == null) {
final PrecomputedText.Params param = new PrecomputedText.Params(paint, textDir,
b.mBreakStrategy, b.mHyphenationFrequency);
measured = PrecomputedText.createWidthOnly(source, param, bufStart, bufEnd);
spanned = (source instanceof Spanned) ? (Spanned) source : null;
} else {
final CharSequence original = measured.getText();
spanned = (original instanceof Spanned) ? (Spanned) original : null;
paragraphInfo = PrecomputedText.createMeasuredParagraphs(source, param, bufStart,
bufEnd, false /* computeLayout */);
}
try {
for (int paraIndex = 0; paraIndex < measured.getParagraphCount(); paraIndex++) {
final int paraStart = measured.getParagraphStart(paraIndex);
final int paraEnd = measured.getParagraphEnd(paraIndex);
for (int paraIndex = 0; paraIndex < paragraphInfo.length; paraIndex++) {
final int paraStart = paraIndex == 0
? bufStart : paragraphInfo[paraIndex - 1].paragraphEnd;
final int paraEnd = paragraphInfo[paraIndex].paragraphEnd;
int firstWidthLineCount = 1;
int firstWidth = outerWidth;
@@ -741,7 +739,7 @@ public class StaticLayout extends Layout {
}
}
final MeasuredParagraph measuredPara = measured.getMeasuredParagraph(paraIndex);
final MeasuredParagraph measuredPara = paragraphInfo[paraIndex].measured;
final char[] chs = measuredPara.getChars();
final int[] spanEndCache = measuredPara.getSpanEndCache().getRawArray();
final int[] fmCache = measuredPara.getFontMetrics().getRawArray();