AI 143709: am: CL 143678 am: CL 143540 Try not to start TextView lines with non-starter characters.
  TextView was previously following the "relaxed" line breaking
  convention and would allow a line break between any two
  ideographic characters.  Tighten that up and do not allow
  line breaks before non-starter characters (sound and iteration
  marks and small Hiragana and Katakana).
  Original author: enf
  Merged from: //branches/cupcake/...
  Original author: android-build
  Merged from: //branches/donutburger/...

Automated import of CL 143709
diff --git a/core/java/android/text/StaticLayout.java b/core/java/android/text/StaticLayout.java
index 686e8f5..c133cf2 100644
--- a/core/java/android/text/StaticLayout.java
+++ b/core/java/android/text/StaticLayout.java
@@ -618,7 +618,9 @@
                          * -    is class HY: a breakpoint
                          *      except when followed by a digit.
                          *
-                         * Ideographs are class ID: breakpoints when adjacent.
+                         * Ideographs are class ID: breakpoints when adjacent,
+                         * except for NS (non-starters), which can be broken
+                         * after but not before.
                          */
 
                         if (c == ' ' || c == '\t' ||
@@ -627,8 +629,8 @@
                              (j + 1 >= next || !Character.isDigit(chs[j + 1 - start]))) ||
                             ((c == '/' || c == '-') &&
                              (j + 1 >= next || !Character.isDigit(chs[j + 1 - start]))) ||
-                            (c >= FIRST_CJK && isIdeographic(c) &&
-                             j + 1 < next && isIdeographic(chs[j + 1 - start]))) {
+                            (c >= FIRST_CJK && isIdeographic(c, true) &&
+                             j + 1 < next && isIdeographic(chs[j + 1 - start], false))) {
                             okwidth = w;
                             ok = j + 1;
 
@@ -807,8 +809,12 @@
      * as being Ideographic (class ID) by the Unicode Line Breaking Algorithm
      * (http://www.unicode.org/unicode/reports/tr14/), and is therefore OK
      * to break between a pair of.
+     *
+     * @param includeNonStarters also return true for category NS
+     *                           (non-starters), which can be broken
+     *                           after but not before.
      */
-    private static final boolean isIdeographic(char c) {
+    private static final boolean isIdeographic(char c, boolean includeNonStarters) {
         if (c >= '\u2E80' && c <= '\u2FFF') {
             return true; // CJK, KANGXI RADICALS, DESCRIPTION SYMBOLS
         }
@@ -816,9 +822,52 @@
             return true; // IDEOGRAPHIC SPACE
         }
         if (c >= '\u3040' && c <= '\u309F') {
+            if (!includeNonStarters) {
+                switch (c) {
+                case '\u3041': //  # HIRAGANA LETTER SMALL A
+                case '\u3043': //  # HIRAGANA LETTER SMALL I
+                case '\u3045': //  # HIRAGANA LETTER SMALL U
+                case '\u3047': //  # HIRAGANA LETTER SMALL E
+                case '\u3049': //  # HIRAGANA LETTER SMALL O
+                case '\u3063': //  # HIRAGANA LETTER SMALL TU
+                case '\u3083': //  # HIRAGANA LETTER SMALL YA
+                case '\u3085': //  # HIRAGANA LETTER SMALL YU
+                case '\u3087': //  # HIRAGANA LETTER SMALL YO
+                case '\u308E': //  # HIRAGANA LETTER SMALL WA
+                case '\u3095': //  # HIRAGANA LETTER SMALL KA
+                case '\u3096': //  # HIRAGANA LETTER SMALL KE
+                case '\u309B': //  # KATAKANA-HIRAGANA VOICED SOUND MARK
+                case '\u309C': //  # KATAKANA-HIRAGANA SEMI-VOICED SOUND MARK
+                case '\u309D': //  # HIRAGANA ITERATION MARK
+                case '\u309E': //  # HIRAGANA VOICED ITERATION MARK
+                    return false;
+                }
+            }
             return true; // Hiragana (except small characters)
         }
         if (c >= '\u30A0' && c <= '\u30FF') {
+            if (!includeNonStarters) {
+                switch (c) {
+                case '\u30A0': //  # KATAKANA-HIRAGANA DOUBLE HYPHEN
+                case '\u30A1': //  # KATAKANA LETTER SMALL A
+                case '\u30A3': //  # KATAKANA LETTER SMALL I
+                case '\u30A5': //  # KATAKANA LETTER SMALL U
+                case '\u30A7': //  # KATAKANA LETTER SMALL E
+                case '\u30A9': //  # KATAKANA LETTER SMALL O
+                case '\u30C3': //  # KATAKANA LETTER SMALL TU
+                case '\u30E3': //  # KATAKANA LETTER SMALL YA
+                case '\u30E5': //  # KATAKANA LETTER SMALL YU
+                case '\u30E7': //  # KATAKANA LETTER SMALL YO
+                case '\u30EE': //  # KATAKANA LETTER SMALL WA
+                case '\u30F5': //  # KATAKANA LETTER SMALL KA
+                case '\u30F6': //  # KATAKANA LETTER SMALL KE
+                case '\u30FB': //  # KATAKANA MIDDLE DOT
+                case '\u30FC': //  # KATAKANA-HIRAGANA PROLONGED SOUND MARK
+                case '\u30FD': //  # KATAKANA ITERATION MARK
+                case '\u30FE': //  # KATAKANA VOICED ITERATION MARK
+                    return false;
+                }
+            }
             return true; // Katakana (except small characters)
         }
         if (c >= '\u3400' && c <= '\u4DB5') {