Merge "Unhide HyphenEdit related methods"
diff --git a/api/current.txt b/api/current.txt
index d82dcad..46fa3f0 100755
--- a/api/current.txt
+++ b/api/current.txt
@@ -13983,6 +13983,7 @@
     method public float getFontSpacing();
     method public java.lang.String getFontVariationSettings();
     method public int getHinting();
+    method public int getHyphenEdit();
     method public float getLetterSpacing();
     method public android.graphics.MaskFilter getMaskFilter();
     method public int getOffsetForAdvance(char[], int, int, int, int, boolean, float);
@@ -14046,6 +14047,7 @@
     method public void setFontFeatureSettings(java.lang.String);
     method public boolean setFontVariationSettings(java.lang.String);
     method public void setHinting(int);
+    method public void setHyphenEdit(int);
     method public void setLetterSpacing(float);
     method public void setLinearText(boolean);
     method public android.graphics.MaskFilter setMaskFilter(android.graphics.MaskFilter);
@@ -43504,6 +43506,22 @@
     method public abstract void handleTag(boolean, java.lang.String, android.text.Editable, org.xml.sax.XMLReader);
   }
 
+  public class Hyphenator {
+    method public static int packHyphenEdit(int, int);
+    method public static int unpackEndHyphenEdit(int);
+    method public static int unpackStartHyphenEdit(int);
+    field public static final int END_HYPHEN_EDIT_INSERT_ARMENIAN_HYPHEN = 3; // 0x3
+    field public static final int END_HYPHEN_EDIT_INSERT_HYPHEN = 2; // 0x2
+    field public static final int END_HYPHEN_EDIT_INSERT_MAQAF = 4; // 0x4
+    field public static final int END_HYPHEN_EDIT_INSERT_UCAS_HYPHEN = 5; // 0x5
+    field public static final int END_HYPHEN_EDIT_INSERT_ZWJ_AND_HYPHEN = 6; // 0x6
+    field public static final int END_HYPHEN_EDIT_NO_EDIT = 0; // 0x0
+    field public static final int END_HYPHEN_EDIT_REPLACE_WITH_HYPHEN = 1; // 0x1
+    field public static final int START_HYPHEN_EDIT_INSERT_HYPHEN = 1; // 0x1
+    field public static final int START_HYPHEN_EDIT_INSERT_ZWJ = 2; // 0x2
+    field public static final int START_HYPHEN_EDIT_NO_EDIT = 0; // 0x0
+  }
+
   public abstract interface InputFilter {
     method public abstract java.lang.CharSequence filter(java.lang.CharSequence, int, int, android.text.Spanned, int, int);
   }
diff --git a/core/java/android/text/Hyphenator.java b/core/java/android/text/Hyphenator.java
index 4f1488e..e4200ac 100644
--- a/core/java/android/text/Hyphenator.java
+++ b/core/java/android/text/Hyphenator.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2018 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -16,15 +16,145 @@
 
 package android.text;
 
+import android.annotation.IntDef;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
 /**
- * Hyphenator just initializes the native implementation of automatic hyphenation,
- * in essence finding valid hyphenation opportunities in a word.
+ * Provides constants and pack/unpack methods for the HyphenEdit.
  *
- * @hide
+ * Hyphenator provides constant values for start of line and end of line modification.
+ * For example, by passing {@link #END_HYPHEN_EDIT_INSERT_HYPHEN} like as follows, HYPHEN(U+2010)
+ * character is appended at the end of line.
+ *
+ * <pre>
+ * <code>
+ *   Paint paint = new Paint();
+ *   paint.setHyphenEdit(Hyphenator.packHyphenEdit(
+ *       Hyphenator.START_HYPHEN_EDIT_NO_EDIT,
+ *       Hyphenator.END_HYPHEN_EDIT_INSERT_HYPHEN));
+ *   paint.measureText("abc", 0, 3);  // Returns the width of "abc‐"
+ *   Canvas.drawText("abc", 0, 3, 0f, 0f, paint);  // Draws "abc‐"
+ * </code>
+ * </pre>
+ *
+ * @see android.graphics.Paint#setHyphenEdit(int)
  */
 public class Hyphenator {
+    private Hyphenator() {}
+
+    /** @hide */
+    @IntDef(prefix = { "START_HYPHEN_EDIT_" }, value = {
+        START_HYPHEN_EDIT_NO_EDIT,
+        START_HYPHEN_EDIT_INSERT_HYPHEN,
+        START_HYPHEN_EDIT_INSERT_ZWJ
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface StartHyphenEdit {}
+
+    /**
+     * An integer representing the starting of the line has no modification for hyphenation.
+     */
+    public static final int START_HYPHEN_EDIT_NO_EDIT = 0x00;
+
+    /**
+     * An integer representing the starting of the line has normal hyphen character (U+002D).
+     */
+    public static final int START_HYPHEN_EDIT_INSERT_HYPHEN = 0x01;
+
+    /**
+     * An integer representing the starting of the line has Zero-Width-Joiner (U+200D).
+     */
+    public static final int START_HYPHEN_EDIT_INSERT_ZWJ = 0x02;
+
+    /** @hide */
+    @IntDef(prefix = { "END_HYPHEN_EDIT_" }, value = {
+        END_HYPHEN_EDIT_NO_EDIT,
+        END_HYPHEN_EDIT_REPLACE_WITH_HYPHEN,
+        END_HYPHEN_EDIT_INSERT_HYPHEN,
+        END_HYPHEN_EDIT_INSERT_ARMENIAN_HYPHEN,
+        END_HYPHEN_EDIT_INSERT_MAQAF,
+        END_HYPHEN_EDIT_INSERT_UCAS_HYPHEN,
+        END_HYPHEN_EDIT_INSERT_ZWJ_AND_HYPHEN
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface EndHyphenEdit {}
+
+    /**
+     * An integer representing the end of the line has no modification for hyphenation.
+     */
+    public static final int END_HYPHEN_EDIT_NO_EDIT = 0x00;
+
+    /**
+     * An integer representing the character at the end of the line is replaced with hyphen
+     * character (U+002D).
+     */
+    public static final int END_HYPHEN_EDIT_REPLACE_WITH_HYPHEN = 0x01;
+
+    /**
+     * An integer representing the end of the line has normal hyphen character (U+002D).
+     */
+    public static final int END_HYPHEN_EDIT_INSERT_HYPHEN = 0x02;
+
+    /**
+     * An integer representing the end of the line has Armentian hyphen (U+058A).
+     */
+    public static final int END_HYPHEN_EDIT_INSERT_ARMENIAN_HYPHEN = 0x03;
+
+    /**
+     * An integer representing the end of the line has maqaf (Hebrew hyphen, U+05BE).
+     */
+    public static final int END_HYPHEN_EDIT_INSERT_MAQAF = 0x04;
+
+    /**
+     * An integer representing the end of the line has Canadian Syllabics hyphen (U+1400).
+     */
+    public static final int END_HYPHEN_EDIT_INSERT_UCAS_HYPHEN = 0x05;
+
+    /**
+     * An integer representing the end of the line has Zero-Width-Joiner (U+200D) followed by normal
+     * hyphen character (U+002D).
+     */
+    public static final int END_HYPHEN_EDIT_INSERT_ZWJ_AND_HYPHEN = 0x06;
+
+    // Following three constants are used for packing start hyphen edit and end hyphen edit into
+    // single integer. Following encodings must be the same as the minikin's one.
+    // See frameworks/minikin/include/Hyphenator.h for more details.
+    private static final int END_HYPHEN_EDIT_MASK = 0x07;  // 0b00111
+    private static final int START_HYPHEN_EDIT_MASK = 0x18;  // 0b11000
+    private static final int START_HYPHEN_EDIT_SHIFT = 0x03;
+
+    /**
+     * Extract start hyphen edit from packed value.
+     */
+    public static @StartHyphenEdit int unpackStartHyphenEdit(int hyphenEdit) {
+        return (hyphenEdit & START_HYPHEN_EDIT_MASK) >> START_HYPHEN_EDIT_SHIFT;
+    }
+
+    /**
+     * Extract end hyphen edit from packed value.
+     */
+    public static @EndHyphenEdit int unpackEndHyphenEdit(int hyphenEdit) {
+        return hyphenEdit & END_HYPHEN_EDIT_MASK;
+    }
+
+    /**
+     * Pack the start hyphen edit and end hyphen edit into single integer.
+     */
+    public static int packHyphenEdit(@StartHyphenEdit int startHyphenEdit,
+            @EndHyphenEdit int endHyphenEdit) {
+        return ((startHyphenEdit << START_HYPHEN_EDIT_SHIFT) & START_HYPHEN_EDIT_MASK)
+                | (endHyphenEdit & END_HYPHEN_EDIT_MASK);
+    }
+
+
+    /**
+     * @hide
+     */
     public static void init() {
         nInit();
     }
+
     private static native void nInit();
 }
diff --git a/core/java/android/text/StaticLayout.java b/core/java/android/text/StaticLayout.java
index 128f860..5adb1ca 100644
--- a/core/java/android/text/StaticLayout.java
+++ b/core/java/android/text/StaticLayout.java
@@ -1216,11 +1216,19 @@
     }
 
     /**
+     * Returns the packed hyphen edit value for this line.
+     *
+     * You can extract start hyphen edit and end hyphen edit by using
+     * {@link Hyphenator#unpackStartHyphenEdit(int)} and
+     * {@link Hyphenator#unpackEndHyphenEdit(int)}.
+     *
+     * @param lineNumber a line number
+     * @return A packed hyphen edit value.
      * @hide
      */
     @Override
-    public int getHyphen(int line) {
-        return mLines[mColumns * line + HYPHEN] & HYPHEN_MASK;
+    public int getHyphen(int lineNumber) {
+        return mLines[mColumns * lineNumber + HYPHEN] & HYPHEN_MASK;
     }
 
     /**
diff --git a/core/java/android/text/TextLine.java b/core/java/android/text/TextLine.java
index 9667b10..bf2d600 100644
--- a/core/java/android/text/TextLine.java
+++ b/core/java/android/text/TextLine.java
@@ -1053,13 +1053,16 @@
         return runIsRtl ? -ret : ret;
     }
 
-    private int adjustHyphenEdit(int start, int limit, int hyphenEdit) {
-        int result = hyphenEdit;
+    private int adjustHyphenEdit(int start, int limit, int packedHyphenEdit) {
+        int result = packedHyphenEdit;
         // Only draw hyphens on first or last run in line. Disable them otherwise.
         if (start > 0) { // not the first run
-            result &= ~Paint.HYPHENEDIT_MASK_START_OF_LINE;
+            result = Hyphenator.packHyphenEdit(Hyphenator.START_HYPHEN_EDIT_NO_EDIT,
+                    Hyphenator.unpackEndHyphenEdit(packedHyphenEdit));
         }
         if (limit < mLen) { // not the last run
+            result = Hyphenator.packHyphenEdit(Hyphenator.unpackStartHyphenEdit(packedHyphenEdit),
+                    Hyphenator.END_HYPHEN_EDIT_NO_EDIT);
             result &= ~Paint.HYPHENEDIT_MASK_END_OF_LINE;
         }
         return result;
diff --git a/graphics/java/android/graphics/Paint.java b/graphics/java/android/graphics/Paint.java
index 7fc1787..6f30653 100644
--- a/graphics/java/android/graphics/Paint.java
+++ b/graphics/java/android/graphics/Paint.java
@@ -1742,26 +1742,52 @@
     }
 
     /**
-     * Get the current value of hyphen edit.
+     * Get the current value of packed hyphen edit.
+     *
+     * You can extract start hyphen edit and end hyphen edit by using
+     * {@link android.text.Hyphenator#unpackStartHyphenEdit(int)} and
+     * {@link android.text.Hyphenator#unpackEndHyphenEdit(int)}.
+     *
+     * The default value is 0 which is equivalent to packed value of
+     * {@link android.text.Hyphenator#START_HYPHEN_EDIT_NO_EDIT} and
+     * {@link android.text.Hyphenator#END_HYPHEN_EDIT_NO_EDIT}.
      *
      * @return the current hyphen edit value
-     *
-     * @hide
+     * @see #setHyphenEdit(int)
      */
     public int getHyphenEdit() {
         return nGetHyphenEdit(mNativePaint);
     }
 
     /**
-     * Set a hyphen edit on the paint (causes a hyphen to be added to text when
-     * measured or drawn).
+     * Set a packed hyphen edit on the paint.
      *
-     * @param hyphen 0 for no edit, 1 for adding a hyphen at the end, etc.
-     *        Definition of various values are in the HyphenEdit class in Minikin's Hyphenator.h.
+     * By setting hyphen edit, the measurement and drawing is performed with modifying hyphenation
+     * at the start of line and end of line. For example, by passing
+     * {@link android.text.Hyphenator#END_HYPHEN_EDIT_INSERT_HYPHEN} like as follows, HYPHEN(U+2010)
+     * character is appended at the end of line.
      *
-     * @hide
+     * <pre>
+     * <code>
+     *   Paint paint = new Paint();
+     *   paint.setHyphenEdit(Hyphenator.packHyphenEdit(
+     *       Hyphenator.START_HYPHEN_EDIT_NO_EDIT,
+     *       Hyphenator.END_HYPHEN_EDIT_INSERT_HYPHEN));
+     *   paint.measureText("abc", 0, 3);  // Returns the width of "abc‐"
+     *   Canvas.drawText("abc", 0, 3, 0f, 0f, paint);  // Draws "abc‐"
+     * </code>
+     * </pre>
+     *
+     * You can pack start hyphen edit and end hyphen edit by
+     * {@link android.text.Hyphenator#packHyphenEdit(int,int)}
+     *
+     * The default value is 0 which is equivalent to packed value of
+     * {@link android.text.Hyphenator#START_HYPHEN_EDIT_NO_EDIT} and
+     * {@link android.text.Hyphenator#END_HYPHEN_EDIT_NO_EDIT}.
+     *
+     * @param hyphen a packed hyphen edit value.
+     * @see #getHyphenEdit()
      */
-    @UnsupportedAppUsage
     public void setHyphenEdit(int hyphen) {
         nSetHyphenEdit(mNativePaint, hyphen);
     }