Revert "Fix build: Revert "Record hyphens from Minikin and draw them""

This reverts commit 5a6eeb3cbe0896ddf4bdccc0b1a81d7aac49821e and
fixes the underlying issue (needed to @hide getHyphen() for subclasses
of Layout, not just the base class), and layoutlib changes for
checkbuild.

Change-Id: I7a2b5f20ae014ea8e224d8c4079cf9131e17e1c1
diff --git a/core/java/android/text/StaticLayout.java b/core/java/android/text/StaticLayout.java
index b47418f..4174df0 100644
--- a/core/java/android/text/StaticLayout.java
+++ b/core/java/android/text/StaticLayout.java
@@ -170,7 +170,8 @@
          * Measurement and break iteration is done in native code. The protocol for using
          * the native code is as follows.
          *
-         * For each paragraph, do a nSetText of the paragraph text. Also do nSetLineWidth.
+         * For each paragraph, do a nSetupParagraph, which sets paragraph text, line width, tab
+         * stops, break strategy (and possibly other parameters in the future).
          *
          * Then, for each run within the paragraph:
          *  - setLocale (this must be done at least for the first run, optional afterwards)
@@ -187,7 +188,7 @@
 
         private void setLocale(Locale locale) {
             if (!locale.equals(mLocale)) {
-                nSetLocale(mNativePtr, locale.toLanguageTag());
+                nSetLocale(mNativePtr, locale.toLanguageTag(), Hyphenator.get(locale));
                 mLocale = locale;
             }
         }
@@ -531,7 +532,7 @@
 
             int[] breaks = lineBreaks.breaks;
             float[] lineWidths = lineBreaks.widths;
-            boolean[] flags = lineBreaks.flags;
+            int[] flags = lineBreaks.flags;
 
             // here is the offset of the starting character of the line we are currently measuring
             int here = paraStart;
@@ -617,7 +618,7 @@
                     fm.top, fm.bottom,
                     v,
                     spacingmult, spacingadd, null,
-                    null, fm, false,
+                    null, fm, 0,
                     needMultiply, measured.mLevels, measured.mDir, measured.mEasy, bufEnd,
                     includepad, trackpad, null,
                     null, bufStart, ellipsize,
@@ -629,7 +630,7 @@
                       int above, int below, int top, int bottom, int v,
                       float spacingmult, float spacingadd,
                       LineHeightSpan[] chooseHt, int[] chooseHtv,
-                      Paint.FontMetricsInt fm, boolean hasTabOrEmoji,
+                      Paint.FontMetricsInt fm, int flags,
                       boolean needMultiply, byte[] chdirs, int dir,
                       boolean easy, int bufEnd, boolean includePad,
                       boolean trackPad, char[] chs,
@@ -722,8 +723,10 @@
         lines[off + mColumns + START] = end;
         lines[off + mColumns + TOP] = v;
 
-        if (hasTabOrEmoji)
-            lines[off + TAB] |= TAB_MASK;
+        // TODO: could move TAB to share same column as HYPHEN, simplifying this code and gaining
+        // one bit for start field
+        lines[off + TAB] |= flags & TAB_MASK;
+        lines[off + HYPHEN] = flags;
 
         lines[off + DIR] |= dir << DIR_SHIFT;
         Directions linedirs = DIRS_ALL_LEFT_TO_RIGHT;
@@ -942,6 +945,14 @@
         return mBottomPadding;
     }
 
+    /**
+     * @hide
+     */
+    @Override
+    public int getHyphen(int line) {
+        return mLines[mColumns * line + HYPHEN] & 0xff;
+    }
+
     @Override
     public int getEllipsisCount(int line) {
         if (mColumns < COLUMNS_ELLIPSIZE) {
@@ -968,7 +979,10 @@
     private static native long nNewBuilder();
     private static native void nFreeBuilder(long nativePtr);
     private static native void nFinishBuilder(long nativePtr);
-    private static native void nSetLocale(long nativePtr, String locale);
+
+    /* package */ static native long nLoadHyphenator(String patternData);
+
+    private static native void nSetLocale(long nativePtr, String locale, long nativeHyphenator);
 
     // Set up paragraph text and settings; done as one big method to minimize jni crossings
     private static native void nSetupParagraph(long nativePtr, char[] text, int length,
@@ -991,22 +1005,23 @@
     // to reduce the number of JNI calls in the common case where the
     // arrays do not have to be resized
     private static native int nComputeLineBreaks(long nativePtr, LineBreaks recycle,
-            int[] recycleBreaks, float[] recycleWidths, boolean[] recycleFlags, int recycleLength);
+            int[] recycleBreaks, float[] recycleWidths, int[] recycleFlags, int recycleLength);
 
     private int mLineCount;
     private int mTopPadding, mBottomPadding;
     private int mColumns;
     private int mEllipsizedWidth;
 
-    private static final int COLUMNS_NORMAL = 3;
-    private static final int COLUMNS_ELLIPSIZE = 5;
+    private static final int COLUMNS_NORMAL = 4;
+    private static final int COLUMNS_ELLIPSIZE = 6;
     private static final int START = 0;
     private static final int DIR = START;
     private static final int TAB = START;
     private static final int TOP = 1;
     private static final int DESCENT = 2;
-    private static final int ELLIPSIS_START = 3;
-    private static final int ELLIPSIS_COUNT = 4;
+    private static final int HYPHEN = 3;
+    private static final int ELLIPSIS_START = 4;
+    private static final int ELLIPSIS_COUNT = 5;
 
     private int[] mLines;
     private Directions[] mLineDirections;
@@ -1028,7 +1043,7 @@
         private static final int INITIAL_SIZE = 16;
         public int[] breaks = new int[INITIAL_SIZE];
         public float[] widths = new float[INITIAL_SIZE];
-        public boolean[] flags = new boolean[INITIAL_SIZE]; // hasTabOrEmoji
+        public int[] flags = new int[INITIAL_SIZE]; // hasTabOrEmoji
         // breaks, widths, and flags should all have the same length
     }