From eccdc6b6984d4ff6253bad7a2bbffd5a64604469 Mon Sep 17 00:00:00 2001 From: Haoyu Zhang Date: Mon, 7 Jan 2019 15:11:46 -0800 Subject: [PATCH] Fix that TextLine overwrites wordSpcing on paint TextLine is using wordSpcing for justification. And previously, TextLine will overwrite wordSpcing even justification is not on. This CL make sure that TextLine only changes wordSpcing when justification is on. Bug: 122471618 Test: atest TextLineTest Change-Id: I6f1e2f6c17b65f92d7a5bb064fdafbf5df9ef8f7 --- core/java/android/text/StaticLayout.java | 4 ++++ core/java/android/text/TextLine.java | 19 +++++++++++++------ .../src/android/text/TextLineTest.java | 12 ++++++++++++ 3 files changed, 29 insertions(+), 6 deletions(-) diff --git a/core/java/android/text/StaticLayout.java b/core/java/android/text/StaticLayout.java index 3d0c6622d8afd..24d746e0dfe2f 100644 --- a/core/java/android/text/StaticLayout.java +++ b/core/java/android/text/StaticLayout.java @@ -376,9 +376,13 @@ public class StaticLayout extends Layout { * Set paragraph 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 #setAlignment}. + * When Justification mode is JUSTIFICATION_MODE_INTER_WORD, wordSpacing on the given + * {@link Paint} will be ignored. This behavior also affects Spans which change the + * wordSpacing. * * @param justificationMode justification mode for the paragraph. * @return this builder, useful for chaining. + * @see Paint#setWordSpacing(float) */ @NonNull public Builder setJustificationMode(@JustificationMode int justificationMode) { diff --git a/core/java/android/text/TextLine.java b/core/java/android/text/TextLine.java index 6eb433abf16c8..949328fd3a990 100644 --- a/core/java/android/text/TextLine.java +++ b/core/java/android/text/TextLine.java @@ -75,8 +75,9 @@ public class TextLine { private int mEllipsisEnd; // Additional width of whitespace for justification. This value is per whitespace, thus - // the line width will increase by mAddedWidth x (number of stretchable whitespaces). - private float mAddedWidth; + // the line width will increase by mAddedWidthForJustify x (number of stretchable whitespaces). + private float mAddedWidthForJustify; + private boolean mIsJustifying; private final TextPaint mWorkPaint = new TextPaint(); private final TextPaint mActivePaint = new TextPaint(); @@ -229,7 +230,8 @@ public class TextLine { } } mTabs = tabStops; - mAddedWidth = 0; + mAddedWidthForJustify = 0; + mIsJustifying = false; mEllipsisStart = ellipsisStart != ellipsisEnd ? ellipsisStart : 0; mEllipsisEnd = ellipsisStart != ellipsisEnd ? ellipsisEnd : 0; @@ -255,7 +257,8 @@ public class TextLine { return; } final float width = Math.abs(measure(end, false, null)); - mAddedWidth = (justifyWidth - width) / spaces; + mAddedWidthForJustify = (justifyWidth - width) / spaces; + mIsJustifying = true; } /** @@ -713,7 +716,9 @@ public class TextLine { TextPaint wp = mWorkPaint; wp.set(mPaint); - wp.setWordSpacing(mAddedWidth); + if (mIsJustifying) { + wp.setWordSpacing(mAddedWidthForJustify); + } int spanStart = runStart; int spanLimit; @@ -849,7 +854,9 @@ public class TextLine { FontMetricsInt fmi, boolean needWidth, int offset, @Nullable ArrayList decorations) { - wp.setWordSpacing(mAddedWidth); + if (mIsJustifying) { + wp.setWordSpacing(mAddedWidthForJustify); + } // Get metrics first (even for empty strings or "0" width runs) if (fmi != null) { expandMetricsFromPaint(fmi, wp); diff --git a/core/tests/coretests/src/android/text/TextLineTest.java b/core/tests/coretests/src/android/text/TextLineTest.java index 61f976a7308d3..2fe882c8f9f8e 100644 --- a/core/tests/coretests/src/android/text/TextLineTest.java +++ b/core/tests/coretests/src/android/text/TextLineTest.java @@ -253,6 +253,18 @@ public class TextLineTest { new float[]{0.0f, -10.0f, -10.0f, -100.0f, -110.0f, -110.0f}); } + @Test + public void testMeasure_wordSpacing() { + final TextPaint paint = new TextPaint(); + paint.setTypeface(TYPEFACE); + paint.setTextSize(10.0f); // make 1em = 10px + paint.setWordSpacing(10.0f); + + TextLine tl = getTextLine("I I", paint); + assertMeasurements(tl, 3, false, + new float[]{0.0f, 10.0f, 120.0f, 130.0f}); + } + @Test public void testHandleRun_ellipsizedReplacementSpan_isSkipped() { final Spannable text = new SpannableStringBuilder("This is a... text");