diff options
| -rw-r--r-- | core/api/current.txt | 2 | ||||
| -rw-r--r-- | core/java/android/text/PrecomputedText.java | 27 | ||||
| -rw-r--r-- | core/java/android/text/flags/flags.aconfig | 7 | ||||
| -rw-r--r-- | graphics/java/android/graphics/text/LineBreakConfig.java | 83 |
4 files changed, 107 insertions, 12 deletions
diff --git a/core/api/current.txt b/core/api/current.txt index c3639b532043..246032731b29 100644 --- a/core/api/current.txt +++ b/core/api/current.txt @@ -17713,12 +17713,14 @@ package android.graphics.text { field @FlaggedApi("com.android.text.flags.no_break_no_hyphenation_span") public static final int HYPHENATION_DISABLED = 0; // 0x0 field @FlaggedApi("com.android.text.flags.no_break_no_hyphenation_span") public static final int HYPHENATION_ENABLED = 1; // 0x1 field @FlaggedApi("com.android.text.flags.no_break_no_hyphenation_span") public static final int HYPHENATION_UNSPECIFIED = -1; // 0xffffffff + field @FlaggedApi("com.android.text.flags.word_style_auto") public static final int LINE_BREAK_STYLE_AUTO = 5; // 0x5 field public static final int LINE_BREAK_STYLE_LOOSE = 1; // 0x1 field public static final int LINE_BREAK_STYLE_NONE = 0; // 0x0 field public static final int LINE_BREAK_STYLE_NORMAL = 2; // 0x2 field @FlaggedApi("com.android.text.flags.no_break_no_hyphenation_span") public static final int LINE_BREAK_STYLE_NO_BREAK = 4; // 0x4 field public static final int LINE_BREAK_STYLE_STRICT = 3; // 0x3 field @FlaggedApi("com.android.text.flags.no_break_no_hyphenation_span") public static final int LINE_BREAK_STYLE_UNSPECIFIED = -1; // 0xffffffff + field @FlaggedApi("com.android.text.flags.word_style_auto") public static final int LINE_BREAK_WORD_STYLE_AUTO = 2; // 0x2 field public static final int LINE_BREAK_WORD_STYLE_NONE = 0; // 0x0 field public static final int LINE_BREAK_WORD_STYLE_PHRASE = 1; // 0x1 field @FlaggedApi("com.android.text.flags.no_break_no_hyphenation_span") public static final int LINE_BREAK_WORD_STYLE_UNSPECIFIED = -1; // 0xffffffff diff --git a/core/java/android/text/PrecomputedText.java b/core/java/android/text/PrecomputedText.java index 517ae4f5c81b..5f6a9bd068c9 100644 --- a/core/java/android/text/PrecomputedText.java +++ b/core/java/android/text/PrecomputedText.java @@ -457,12 +457,21 @@ public class PrecomputedText implements Spannable { } else { hyphenationMode = MeasuredText.Builder.HYPHENATION_MODE_NONE; } + LineBreakConfig config = params.getLineBreakConfig(); + if (config.getLineBreakWordStyle() == LineBreakConfig.LINE_BREAK_WORD_STYLE_AUTO + && pct.getParagraphCount() != 1) { + // If the text has multiple paragraph, resolve line break word style auto to none. + config = new LineBreakConfig.Builder() + .merge(config) + .setLineBreakWordStyle(LineBreakConfig.LINE_BREAK_WORD_STYLE_NONE) + .build(); + } ArrayList<ParagraphInfo> result = new ArrayList<>(); for (int i = 0; i < pct.getParagraphCount(); ++i) { final int paraStart = pct.getParagraphStart(i); final int paraEnd = pct.getParagraphEnd(i); result.add(new ParagraphInfo(paraEnd, MeasuredParagraph.buildForStaticLayout( - params.getTextPaint(), params.getLineBreakConfig(), pct, paraStart, paraEnd, + params.getTextPaint(), config, pct, paraStart, paraEnd, params.getTextDirection(), hyphenationMode, computeLayout, true, pct.getMeasuredParagraph(i), null /* no recycle */))); } @@ -489,6 +498,7 @@ public class PrecomputedText implements Spannable { hyphenationMode = MeasuredText.Builder.HYPHENATION_MODE_NONE; } + LineBreakConfig config = null; int paraEnd = 0; for (int paraStart = start; paraStart < end; paraStart = paraEnd) { paraEnd = TextUtils.indexOf(text, LINE_FEED, paraStart, end); @@ -500,8 +510,21 @@ public class PrecomputedText implements Spannable { paraEnd++; // Includes LINE_FEED(U+000A) to the prev paragraph. } + if (config == null) { + config = params.getLineBreakConfig(); + if (config.getLineBreakWordStyle() == LineBreakConfig.LINE_BREAK_WORD_STYLE_AUTO + && !(paraStart == start && paraEnd == end)) { + // If the text has multiple paragraph, resolve line break word style auto to + // none. + config = new LineBreakConfig.Builder() + .merge(config) + .setLineBreakWordStyle(LineBreakConfig.LINE_BREAK_WORD_STYLE_NONE) + .build(); + } + } + result.add(new ParagraphInfo(paraEnd, MeasuredParagraph.buildForStaticLayout( - params.getTextPaint(), params.getLineBreakConfig(), text, paraStart, paraEnd, + params.getTextPaint(), config, text, paraStart, paraEnd, params.getTextDirection(), hyphenationMode, computeLayout, computeBounds, null /* no hint */, null /* no recycle */))); diff --git a/core/java/android/text/flags/flags.aconfig b/core/java/android/text/flags/flags.aconfig index cf36d895b422..43c38f319713 100644 --- a/core/java/android/text/flags/flags.aconfig +++ b/core/java/android/text/flags/flags.aconfig @@ -68,3 +68,10 @@ flag { description: "Feature flag for deprecating UI fonts. By setting true for this feature flag, the elegant text height of will be turned on by default unless explicitly setting it to false by attribute or Java API call." bug: "279646685" } + +flag { + name: "word_style_auto" + namespace: "text" + description: "A feature flag that implements line break word style auto." + bug: "280005585" +} diff --git a/graphics/java/android/graphics/text/LineBreakConfig.java b/graphics/java/android/graphics/text/LineBreakConfig.java index dc1773bd7290..621958562b94 100644 --- a/graphics/java/android/graphics/text/LineBreakConfig.java +++ b/graphics/java/android/graphics/text/LineBreakConfig.java @@ -17,11 +17,17 @@ package android.graphics.text; import static com.android.text.flags.Flags.FLAG_NO_BREAK_NO_HYPHENATION_SPAN; +import static com.android.text.flags.Flags.FLAG_WORD_STYLE_AUTO; import android.annotation.FlaggedApi; import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; +import android.app.compat.CompatChanges; +import android.compat.annotation.ChangeId; +import android.compat.annotation.EnabledSince; +import android.os.Build; +import android.os.LocaleList; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; @@ -37,6 +43,14 @@ import java.util.Objects; public final class LineBreakConfig { /** + * A feature ID for automatic line break word style. + * @hide + */ + @ChangeId + @EnabledSince(targetSdkVersion = Build.VERSION_CODES.VANILLA_ICE_CREAM) + public static final long WORD_STYLE_AUTO = 280005585L; + + /** * No hyphenation preference is specified. * * <p> @@ -112,8 +126,11 @@ public final class LineBreakConfig { * </pre> * * <p> - * This value is resolved to {@link #LINE_BREAK_STYLE_NONE} if this value is used for text - * layout/rendering. + * This value is resolved to {@link #LINE_BREAK_STYLE_NONE} if the target SDK version is API + * {@link Build.VERSION_CODES#UPSIDE_DOWN_CAKE} or before and this value is used for text + * layout/rendering. This value is resolved to {@link #LINE_BREAK_STYLE_AUTO} if the target SDK + * version is API {@link Build.VERSION_CODES#VANILLA_ICE_CREAM} or after and this value is + * used for text layout/rendering. */ @FlaggedApi(FLAG_NO_BREAK_NO_HYPHENATION_SPAN) public static final int LINE_BREAK_STYLE_UNSPECIFIED = -1; @@ -154,10 +171,29 @@ public final class LineBreakConfig { @FlaggedApi(FLAG_NO_BREAK_NO_HYPHENATION_SPAN) public static final int LINE_BREAK_STYLE_NO_BREAK = 4; + /** + * A special value for the line breaking style option. + * + * <p> + * The auto option for the line break style set the line break style based on the locale of the + * text rendering context. You can specify the context locale by + * {@link android.widget.TextView#setTextLocales(LocaleList)} or + * {@link android.graphics.Paint#setTextLocales(LocaleList)}. + * + * <p> + * In the API {@link Build.VERSION_CODES#VANILLA_ICE_CREAM}, auto option does followings: + * - If at least one locale in the locale list contains Japanese script, this option is + * equivalent to {@link #LINE_BREAK_STYLE_STRICT}. + * - Otherwise, this option is equivalent to {@link #LINE_BREAK_STYLE_NONE}. + */ + @FlaggedApi(FLAG_WORD_STYLE_AUTO) + public static final int LINE_BREAK_STYLE_AUTO = 5; + /** @hide */ @IntDef(prefix = { "LINE_BREAK_STYLE_" }, value = { LINE_BREAK_STYLE_NONE, LINE_BREAK_STYLE_LOOSE, LINE_BREAK_STYLE_NORMAL, - LINE_BREAK_STYLE_STRICT, LINE_BREAK_STYLE_UNSPECIFIED, LINE_BREAK_STYLE_NO_BREAK + LINE_BREAK_STYLE_STRICT, LINE_BREAK_STYLE_UNSPECIFIED, LINE_BREAK_STYLE_NO_BREAK, + LINE_BREAK_STYLE_AUTO }) @Retention(RetentionPolicy.SOURCE) public @interface LineBreakStyle {} @@ -183,8 +219,11 @@ public final class LineBreakConfig { * // LINE_BREAK_WORD_STYLE_PHRASE for line break word style. * </pre> * - * This value is resolved to {@link #LINE_BREAK_WORD_STYLE_NONE} if this value is used for - * text layout/rendering. + * This value is resolved to {@link #LINE_BREAK_WORD_STYLE_NONE} if the target SDK version is + * API {@link Build.VERSION_CODES#UPSIDE_DOWN_CAKE} or before and this value is used for text + * layout/rendering. This value is resolved to {@link #LINE_BREAK_WORD_STYLE_AUTO} if the target + * SDK version is API {@link Build.VERSION_CODES#VANILLA_ICE_CREAM} or after and this value is + * used for text layout/rendering. */ @FlaggedApi(FLAG_NO_BREAK_NO_HYPHENATION_SPAN) public static final int LINE_BREAK_WORD_STYLE_UNSPECIFIED = -1; @@ -204,9 +243,29 @@ public final class LineBreakConfig { */ public static final int LINE_BREAK_WORD_STYLE_PHRASE = 1; + /** + * A special value for the line breaking word style option. + * + * <p> + * The auto option for the line break word style does some heuristics based on locales and line + * count. + * + * <p> + * In the API {@link Build.VERSION_CODES#VANILLA_ICE_CREAM}, auto option does followings: + * - If at least one locale in the locale list contains Korean script, this option is equivalent + * to {@link #LINE_BREAK_WORD_STYLE_PHRASE}. + * - If not, then if at least one locale in the locale list contains Japanese script, this + * option is equivalent to {@link #LINE_BREAK_WORD_STYLE_PHRASE} if the result of its line + * count is less than 5 lines. + * - Otherwise, this option is equivalent to {@link #LINE_BREAK_WORD_STYLE_NONE}. + */ + @FlaggedApi(FLAG_WORD_STYLE_AUTO) + public static final int LINE_BREAK_WORD_STYLE_AUTO = 2; + /** @hide */ @IntDef(prefix = { "LINE_BREAK_WORD_STYLE_" }, value = { - LINE_BREAK_WORD_STYLE_NONE, LINE_BREAK_WORD_STYLE_PHRASE, LINE_BREAK_WORD_STYLE_UNSPECIFIED + LINE_BREAK_WORD_STYLE_NONE, LINE_BREAK_WORD_STYLE_PHRASE, LINE_BREAK_WORD_STYLE_UNSPECIFIED, + LINE_BREAK_WORD_STYLE_AUTO }) @Retention(RetentionPolicy.SOURCE) public @interface LineBreakWordStyle {} @@ -425,11 +484,13 @@ public final class LineBreakConfig { * @hide */ public static @LineBreakStyle int getResolvedLineBreakStyle(@Nullable LineBreakConfig config) { + final int defaultStyle = CompatChanges.isChangeEnabled(WORD_STYLE_AUTO) + ? LINE_BREAK_STYLE_AUTO : LINE_BREAK_STYLE_NONE; if (config == null) { - return LINE_BREAK_STYLE_NONE; + return defaultStyle; } return config.mLineBreakStyle == LINE_BREAK_STYLE_UNSPECIFIED - ? LINE_BREAK_STYLE_NONE : config.mLineBreakStyle; + ? defaultStyle : config.mLineBreakStyle; } /** @@ -451,11 +512,13 @@ public final class LineBreakConfig { */ public static @LineBreakWordStyle int getResolvedLineBreakWordStyle( @Nullable LineBreakConfig config) { + final int defaultWordStyle = CompatChanges.isChangeEnabled(WORD_STYLE_AUTO) + ? LINE_BREAK_WORD_STYLE_AUTO : LINE_BREAK_WORD_STYLE_NONE; if (config == null) { - return LINE_BREAK_WORD_STYLE_NONE; + return defaultWordStyle; } return config.mLineBreakWordStyle == LINE_BREAK_WORD_STYLE_UNSPECIFIED - ? LINE_BREAK_WORD_STYLE_NONE : config.mLineBreakWordStyle; + ? defaultWordStyle : config.mLineBreakWordStyle; } /** |