diff options
| author | Seigo Nonaka <nona@google.com> | 2018-02-01 21:39:24 -0800 |
|---|---|---|
| committer | Seigo Nonaka <nona@google.com> | 2018-02-12 20:50:41 -0800 |
| commit | 7fd36d19e309ea515b4048cfaabb8035ceab7baf (patch) | |
| tree | 30db8688e29ada27b365300ed08014a220464517 /core/java/android/widget/TextView.java | |
| parent | d3905e654452c68390835e31fcb752884e57a67b (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.java | 101 |
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() { |
