Take padding information into StaticLayout

This is useful for figuring out if we should adjust width of text
in case the overhangs are more than available padding.

Bug: 63938206
Test: pending
Change-Id: I04592a7cbce264fe133e17e4df0daee626a99d85
diff --git a/core/java/android/text/Layout.java b/core/java/android/text/Layout.java
index 25f791b..c3b2a16 100644
--- a/core/java/android/text/Layout.java
+++ b/core/java/android/text/Layout.java
@@ -1915,8 +1915,7 @@
         return margin;
     }
 
-    /* package */
-    static float measurePara(TextPaint paint, CharSequence text, int start, int end,
+    private static float measurePara(TextPaint paint, CharSequence text, int start, int end,
             TextDirectionHeuristic textDir) {
         MeasuredText mt = MeasuredText.obtain();
         TextLine tl = TextLine.obtain();
diff --git a/core/java/android/text/StaticLayout.java b/core/java/android/text/StaticLayout.java
index 77e381a..8e0ad63 100644
--- a/core/java/android/text/StaticLayout.java
+++ b/core/java/android/text/StaticLayout.java
@@ -119,6 +119,8 @@
             b.mLeftIndents = null;
             b.mRightIndents = null;
             b.mLocales = null;
+            b.mLeftPaddings = null;
+            b.mRightPaddings = null;
             nFinishBuilder(b.mNativePtr);
             sPool.release(b);
         }
@@ -130,6 +132,8 @@
             mPaint = null;
             mLeftIndents = null;
             mRightIndents = null;
+            mLeftPaddings = null;
+            mRightPaddings = null;
             mMeasuredText.finish();
         }
 
@@ -358,6 +362,28 @@
         }
 
         /**
+         * Set available paddings to draw overhanging text on. Arguments are arrays holding the
+         * amount of padding available, one per line, measured in pixels. For lines past the last
+         * element in the array, the last element repeats.
+         *
+         * The individual padding amounts should be non-negative. The result of passing negative
+         * paddings is undefined.
+         *
+         * @param leftPaddings array of amounts of available padding for left margin, in pixels
+         * @param rightPaddings array of amounts of available padding for right margin, in pixels
+         * @return this builder, useful for chaining
+         *
+         * @hide
+         */
+        @NonNull
+        public Builder setAvailablePaddings(@Nullable int[] leftPaddings,
+                @Nullable int[] rightPaddings) {
+            mLeftPaddings = leftPaddings;
+            mRightPaddings = rightPaddings;
+            return this;
+        }
+
+        /**
          * 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}.
@@ -484,6 +510,8 @@
         private int mHyphenationFrequency;
         @Nullable private int[] mLeftIndents;
         @Nullable private int[] mRightIndents;
+        @Nullable private int[] mLeftPaddings;
+        @Nullable private int[] mRightPaddings;
         private int mJustificationMode;
         private boolean mAddLastLineLineSpacing;
 
@@ -644,6 +672,8 @@
 
         mLeftIndents = b.mLeftIndents;
         mRightIndents = b.mRightIndents;
+        mLeftPaddings = b.mLeftPaddings;
+        mRightPaddings = b.mRightPaddings;
         setJustificationMode(b.mJustificationMode);
 
         generate(b, b.mIncludePad, b.mIncludePad);
@@ -785,7 +815,10 @@
                     firstWidth, firstWidthLineCount, restWidth,
                     variableTabStops, TAB_INCREMENT, b.mBreakStrategy, b.mHyphenationFrequency,
                     // TODO: Support more justification mode, e.g. letter spacing, stretching.
-                    b.mJustificationMode != Layout.JUSTIFICATION_MODE_NONE, indents, mLineCount);
+                    b.mJustificationMode != Layout.JUSTIFICATION_MODE_NONE,
+                    // TODO: indents and paddings don't need to get passed to native code for every
+                    // paragraph. Pass them to native code just once.
+                    indents, mLeftPaddings, mRightPaddings, mLineCount);
 
             // measurement has to be done before performing line breaking
             // but we don't want to recompute fontmetrics or span ranges the
@@ -1506,7 +1539,8 @@
             @FloatRange(from = 0.0f) float restWidth, @Nullable int[] variableTabStops,
             int defaultTabStop, @BreakStrategy int breakStrategy,
             @HyphenationFrequency int hyphenationFrequency, boolean isJustified,
-            @Nullable int[] indents, @IntRange(from = 0) int indentsOffset);
+            @Nullable int[] indents, @Nullable int[] leftPaddings, @Nullable int[] rightPaddings,
+            @IntRange(from = 0) int indentsOffset);
 
     private static native float nAddStyleRun(
             /* non zero */ long nativePtr, /* non zero */ long nativePaint,
@@ -1594,4 +1628,6 @@
 
     @Nullable private int[] mLeftIndents;
     @Nullable private int[] mRightIndents;
+    @Nullable private int[] mLeftPaddings;
+    @Nullable private int[] mRightPaddings;
 }
diff --git a/core/jni/android_text_StaticLayout.cpp b/core/jni/android_text_StaticLayout.cpp
index 6d861e8..9afb7f3 100644
--- a/core/jni/android_text_StaticLayout.cpp
+++ b/core/jni/android_text_StaticLayout.cpp
@@ -87,7 +87,8 @@
 static void nSetupParagraph(JNIEnv* env, jclass, jlong nativePtr, jcharArray text, jint length,
         jfloat firstWidth, jint firstWidthLineLimit, jfloat restWidth,
         jintArray variableTabStops, jint defaultTabStop, jint strategy, jint hyphenFrequency,
-        jboolean isJustified, jintArray indents, jint indentsOffset) {
+        jboolean isJustified, jintArray indents, jintArray leftPaddings, jintArray rightPaddings,
+        jint indentsOffset) {
     minikin::LineBreaker* b = reinterpret_cast<minikin::LineBreaker*>(nativePtr);
     b->resize(length);
     env->GetCharArrayRegion(text, 0, length, b->buffer());
@@ -245,7 +246,7 @@
     {"nFreeBuilder", "(J)V", (void*) nFreeBuilder},
     {"nFinishBuilder", "(J)V", (void*) nFinishBuilder},
     {"nLoadHyphenator", "(Ljava/nio/ByteBuffer;III)J", (void*) nLoadHyphenator},
-    {"nSetupParagraph", "(J[CIFIF[IIIIZ[II)V", (void*) nSetupParagraph},
+    {"nSetupParagraph", "(J[CIFIF[IIIIZ[I[I[II)V", (void*) nSetupParagraph},
     {"nAddStyleRun", "(JJIIZLjava/lang/String;[J)F", (void*) nAddStyleRun},
     {"nAddMeasuredRun", "(JII[F)V", (void*) nAddMeasuredRun},
     {"nAddReplacementRun", "(JIIF)V", (void*) nAddReplacementRun},