Merge "Fix that TextLine overwrites wordSpcing on paint"
diff --git a/core/java/android/text/StaticLayout.java b/core/java/android/text/StaticLayout.java
index 3d0c662..24d746e 100644
--- a/core/java/android/text/StaticLayout.java
+++ b/core/java/android/text/StaticLayout.java
@@ -376,9 +376,13 @@
          * 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 6eb433a..949328f 100644
--- a/core/java/android/text/TextLine.java
+++ b/core/java/android/text/TextLine.java
@@ -75,8 +75,9 @@
     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 @@
             }
         }
         mTabs = tabStops;
-        mAddedWidth = 0;
+        mAddedWidthForJustify = 0;
+        mIsJustifying = false;
 
         mEllipsisStart = ellipsisStart != ellipsisEnd ? ellipsisStart : 0;
         mEllipsisEnd = ellipsisStart != ellipsisEnd ? ellipsisEnd : 0;
@@ -255,7 +257,8 @@
             return;
         }
         final float width = Math.abs(measure(end, false, null));
-        mAddedWidth = (justifyWidth - width) / spaces;
+        mAddedWidthForJustify = (justifyWidth - width) / spaces;
+        mIsJustifying = true;
     }
 
     /**
@@ -713,7 +716,9 @@
 
         TextPaint wp = mWorkPaint;
         wp.set(mPaint);
-        wp.setWordSpacing(mAddedWidth);
+        if (mIsJustifying) {
+            wp.setWordSpacing(mAddedWidthForJustify);
+        }
 
         int spanStart = runStart;
         int spanLimit;
@@ -849,7 +854,9 @@
             FontMetricsInt fmi, boolean needWidth, int offset,
             @Nullable ArrayList<DecorationInfo> 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 61f976a..2fe882c 100644
--- a/core/tests/coretests/src/android/text/TextLineTest.java
+++ b/core/tests/coretests/src/android/text/TextLineTest.java
@@ -254,6 +254,18 @@
     }
 
     @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");