summaryrefslogtreecommitdiff
path: root/core/java/android/widget/TextView.java
diff options
context:
space:
mode:
authorSeigo Nonaka <nona@google.com>2018-02-01 21:39:24 -0800
committerSeigo Nonaka <nona@google.com>2018-02-12 20:50:41 -0800
commit7fd36d19e309ea515b4048cfaabb8035ceab7baf (patch)
tree30db8688e29ada27b365300ed08014a220464517 /core/java/android/widget/TextView.java
parentd3905e654452c68390835e31fcb752884e57a67b (diff)
Reorganize MeasuredText API
This CL changes the MeasuredText API: - Rename MeasuredText to PrecomputedText. - PrecomputedText is no longer a Spanned. - Introduce PrecomputedText.Param which holds all text layout parameters. - Add API to get PrecomputedText.Param from TextView. - Remove MeasuredText.Builder and add PrecomputedText.create method instead. - Remove setRange from MeasuredText since it is not for normal use case. (It can not be used for TextView) Here is a performance scores: (median, walleye-userdebug, N=20) StaticLayout creation time (w/o patch -> w/ patch) PrecomputedText Balanced Hyphenation : 743,615 -> 737,145: (-0.9%) PrecomputedText Balanced NoHyphenation: 551,544 -> 542,715: (-1.6%) PrecomputedText Greedy Hyphenation : 500,343 -> 499,601: (-0.1%) PrecomputedText Greedy NoHyphenation : 497,987 -> 492,587: (-1.1%) RandomText Balanced Hyphenation : 19,100,592 -> 19,135,289: (+0.2%) RandomText Balanced NoHyphenation : 8,015,088 -> 7,954,260: (-0.8%) RandomText Greedy Hyphenation : 7,950,915 -> 7,877,424: (-0.9%) RandomText Greedy NoHyphenation : 7,939,337 -> 7,863,471: (-1.0%) PrecomputedText creation time (w/o patch -> w/ patch) NoStyled Hyphenation : 18,935,638 -> 18,925,422: (-0.1%) NoStyled Hyphenation WidthOnly : 18,469,726 -> 18,978,413: (+2.8%) NoStyled NoHyphenation : 7,940,792 -> 7,919,127: (-0.3%) NoStyled NoHyphenation WidthOnly : 7,463,230 -> 7,922,643: (+6.2%) Styled Hyphenation : 14,822,501 -> 14,809,017: (-0.1%) Styled Hyphenation WidthOnly : 13,891,770 -> 14,656,617: (+5.5%) Styled NoHyphenation : 14,511,134 -> 14,301,503: (-1.4%) Styled NoHyphenation WidthOnly : 13,495,345 -> 14,264,314: (+5.7%) StaticLayout draw time (w/o patch -> w/ patch) PrecomputedText NoStyled : 663,974 -> 661,610: (-0.4%) PrecomputedText NoStyled WithoutCache : 648,294 -> 648,766: (+0.1%) PrecomputedText Styled : 879,322 -> 852,770: (-3.0%) PrecomputedText Styled WithoutCache : 1,084,570 -> 1,110,147: (+2.4%) RandomText NoStyled : 565,682 -> 555,435: (-1.8%) RandomText NoStyled WithoutCache : 9,070,533 -> 9,064,825: (-0.1%) RandomText Styled : 2,955,202 -> 2,962,008: (+0.2%) RandomText Styled WithoutCache : 12,242,325 -> 12,228,573: (-0.1%) Bug: 67504091 Bug: 73091756 Test: bit FrameworksCoreTests:android.text. Test: atest CtsWidgetTestCases:EditTextTest \ CtsWidgetTestCases:TextViewFadingEdgeTest \ FrameworksCoreTests:TextViewFallbackLineSpacingTest \ FrameworksCoreTests:TextViewTest FrameworksCoreTests:TypefaceTest \ CtsGraphicsTestCases:TypefaceTest CtsWidgetTestCases:TextViewTest \ CtsTextTestCases Change-Id: I7db9e2ca4db68a16648cfb8fcf63555f501304c2
Diffstat (limited to 'core/java/android/widget/TextView.java')
-rw-r--r--core/java/android/widget/TextView.java101
1 files changed, 94 insertions, 7 deletions
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index 5710db3ce8e0..f6e771a9605e 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -80,8 +80,8 @@ import android.text.GraphicsOperations;
import android.text.InputFilter;
import android.text.InputType;
import android.text.Layout;
-import android.text.MeasuredText;
import android.text.ParcelableSpan;
+import android.text.PrecomputedText;
import android.text.Selection;
import android.text.SpanWatcher;
import android.text.Spannable;
@@ -637,6 +637,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
private CharSequence mText;
private CharSequence mTransformed;
private BufferType mBufferType = BufferType.NORMAL;
+ private PrecomputedText mPrecomputed;
private CharSequence mHint;
private Layout mHintLayout;
@@ -4085,6 +4086,80 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
}
/**
+ * Gets the parameters for text layout precomputation, for use with {@link PrecomputedText}
+ *
+ * @return A current {@link PrecomputedText.Params}
+ */
+ public @NonNull PrecomputedText.Params getTextMetricsParams() {
+ return new PrecomputedText.Params(new TextPaint(mTextPaint), getTextDirectionHeuristic(),
+ mBreakStrategy, mHyphenationFrequency);
+ }
+
+ /**
+ * Apply the text layout parameter.
+ */
+ public void setTextMetricsParams(@NonNull PrecomputedText.Params params) {
+ mTextPaint.set(params.getTextPaint());
+ mTextDir = params.getTextDirection();
+ mBreakStrategy = params.getBreakStrategy();
+ mHyphenationFrequency = params.getHyphenationFrequency();
+ if (mLayout != null) {
+ nullLayouts();
+ requestLayout();
+ invalidate();
+ }
+ }
+
+ /**
+ * Sets the precomputed text.
+ *
+ * If the parameters for the precomputed text is different from current text view parameters,
+ * apply the parameteres to the text view too.
+ *
+ * @param text A precomputed text.
+ */
+ public void setPrecomputedTextAndParams(@NonNull PrecomputedText text) {
+ Preconditions.checkNotNull(text);
+ final PrecomputedText.Params params = text.getParams();
+ if (!params.sameTextMetrics(getTextMetricsParams())) {
+ setTextMetricsParams(params);
+ }
+ setText(text.getText());
+ if (mTransformed != text.getText()) {
+ // setText modified given text for some reasons, selection, transformation, etc.
+ // Can't use computed result.
+ return;
+ } else {
+ mPrecomputed = text;
+ }
+ }
+
+ /**
+ * Sets the precomputed text.
+ *
+ * If the parameters for the precomputed text is different from current text view parameters,
+ * throws {@link IllegalArgumentException}.
+ *
+ * @param text A precomputed text.
+ */
+ public void setPrecomputedTextOrThrow(@NonNull PrecomputedText text) {
+ Preconditions.checkNotNull(text);
+ final PrecomputedText.Params params = text.getParams();
+ if (!params.sameTextMetrics(getTextMetricsParams())) {
+ throw new IllegalArgumentException(
+ "The precomputed configuration is different from this TextView.");
+ }
+ setText(text.getText());
+ if (mTransformed != text.getText()) {
+ // setText modified given text for some reasons, selection, transformation, etc.
+ // Can't use computed result.
+ // TODO: Do we throw an exception here too?
+ } else {
+ mPrecomputed = text;
+ }
+ }
+
+ /**
* Set justification mode. The default value is {@link Layout#JUSTIFICATION_MODE_NONE}. If the
* last line is too short for justification, the last line will be displayed with the
* alignment set by {@link android.view.View#setTextAlignment}.
@@ -5519,6 +5594,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
private void setText(CharSequence text, BufferType type,
boolean notifyBefore, int oldlen) {
+ mPrecomputed = null;
mTextSetFromXmlOrResourceId = false;
if (text == null) {
text = "";
@@ -5577,7 +5653,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
if (imm != null) imm.restartInput(this);
} else if (type == BufferType.SPANNABLE || mMovement != null) {
text = mSpannableFactory.newSpannable(text);
- } else if (!(text instanceof MeasuredText || text instanceof CharWrapper)) {
+ } else if (!(text instanceof CharWrapper)) {
text = TextUtils.stringOrSpannedString(text);
}
@@ -8244,7 +8320,8 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
result = builder.build();
} else {
if (boring == UNKNOWN_BORING) {
- boring = BoringLayout.isBoring(mTransformed, mTextPaint, mTextDir, mBoring);
+ boring = BoringLayout.isBoring(mTransformed, mPrecomputed, mTextPaint, mTextDir,
+ mBoring);
if (boring != null) {
mBoring = boring;
}
@@ -8282,9 +8359,15 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
}
}
if (result == null) {
- StaticLayout.Builder builder = StaticLayout.Builder.obtain(mTransformed,
- 0, mTransformed.length(), mTextPaint, wantWidth)
- .setAlignment(alignment)
+ StaticLayout.Builder builder;
+ if (mPrecomputed != null) {
+ builder = StaticLayout.Builder.obtain(mPrecomputed, 0,
+ mPrecomputed.getText().length(), mTextPaint, wantWidth);
+ } else {
+ builder = StaticLayout.Builder.obtain(mTransformed, 0, mTransformed.length(),
+ mTextPaint, wantWidth);
+ }
+ builder.setAlignment(alignment)
.setTextDirection(mTextDir)
.setLineSpacing(mSpacingAdd, mSpacingMult)
.setIncludePad(mIncludePad)
@@ -8411,7 +8494,8 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
}
if (des < 0) {
- boring = BoringLayout.isBoring(mTransformed, mTextPaint, mTextDir, mBoring);
+ boring = BoringLayout.isBoring(mTransformed, mPrecomputed, mTextPaint, mTextDir,
+ mBoring);
if (boring != null) {
mBoring = boring;
}
@@ -11696,6 +11780,9 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
}
/**
+ * Returns the current {@link TextDirectionHeuristic}
+ *
+ * @return A {@link TextDirectionHeuristic}.
* @hide
*/
protected TextDirectionHeuristic getTextDirectionHeuristic() {