diff options
| author | Roozbeh Pournader <roozbeh@google.com> | 2015-05-12 12:01:06 -0700 |
|---|---|---|
| committer | Roozbeh Pournader <roozbeh@google.com> | 2015-05-12 14:56:57 -0700 |
| commit | 95c7a13f2ac4f31ed3aaec9b47b9a29a3dbca978 (patch) | |
| tree | 9fc3e976118f16aab4dd5279e84e6eb117b4f3f8 /core/java | |
| parent | d2c05188b669256ab9d6024ad5793e0ca891fed0 (diff) | |
Add hyphenationFrequency attribute to TextView and StaticLayout.
This patch adds plumbing to TextView and StaticLayout to control the
frequency of automatic hyphenation used in laying out paragraphs.
Bug: 21038249
Change-Id: Ib45de190eb0a1ed738e69fd61f2b39561b11aec7
Diffstat (limited to 'core/java')
| -rw-r--r-- | core/java/android/text/DynamicLayout.java | 10 | ||||
| -rw-r--r-- | core/java/android/text/Layout.java | 29 | ||||
| -rw-r--r-- | core/java/android/text/StaticLayout.java | 22 | ||||
| -rw-r--r-- | core/java/android/widget/TextView.java | 43 |
4 files changed, 95 insertions, 9 deletions
diff --git a/core/java/android/text/DynamicLayout.java b/core/java/android/text/DynamicLayout.java index fc65f63f27b2..e99a960fb473 100644 --- a/core/java/android/text/DynamicLayout.java +++ b/core/java/android/text/DynamicLayout.java @@ -79,7 +79,8 @@ public class DynamicLayout extends Layout boolean includepad, TextUtils.TruncateAt ellipsize, int ellipsizedWidth) { this(base, display, paint, width, align, TextDirectionHeuristics.FIRSTSTRONG_LTR, - spacingmult, spacingadd, includepad, StaticLayout.BREAK_STRATEGY_SIMPLE, + spacingmult, spacingadd, includepad, + StaticLayout.BREAK_STRATEGY_SIMPLE, StaticLayout.HYPHENATION_FREQUENCY_NONE, ellipsize, ellipsizedWidth); } @@ -96,7 +97,7 @@ public class DynamicLayout extends Layout TextPaint paint, int width, Alignment align, TextDirectionHeuristic textDir, float spacingmult, float spacingadd, - boolean includepad, int breakStrategy, + boolean includepad, int breakStrategy, int hyphenationFrequency, TextUtils.TruncateAt ellipsize, int ellipsizedWidth) { super((ellipsize == null) ? display @@ -122,6 +123,7 @@ public class DynamicLayout extends Layout mIncludePad = includepad; mBreakStrategy = breakStrategy; + mHyphenationFrequency = hyphenationFrequency; /* * This is annoying, but we can't refer to the layout until @@ -293,7 +295,8 @@ public class DynamicLayout extends Layout .setLineSpacing(getSpacingAdd(), getSpacingMultiplier()) .setEllipsizedWidth(mEllipsizedWidth) .setEllipsize(mEllipsizeAt) - .setBreakStrategy(mBreakStrategy); + .setBreakStrategy(mBreakStrategy) + .setHyphenationFrequency(mHyphenationFrequency); reflowed.generate(b, false, true); int n = reflowed.getLineCount(); @@ -719,6 +722,7 @@ public class DynamicLayout extends Layout private int mEllipsizedWidth; private TextUtils.TruncateAt mEllipsizeAt; private int mBreakStrategy; + private int mHyphenationFrequency; private PackedIntVector mInts; private PackedObjectVector<Directions> mObjects; diff --git a/core/java/android/text/Layout.java b/core/java/android/text/Layout.java index 60de02a77d10..f176240dbb73 100644 --- a/core/java/android/text/Layout.java +++ b/core/java/android/text/Layout.java @@ -71,6 +71,35 @@ public abstract class Layout { */ public static final int BREAK_STRATEGY_BALANCED = 2; + /** @hide */ + @IntDef({HYPHENATION_FREQUENCY_NORMAL, HYPHENATION_FREQUENCY_FULL, + HYPHENATION_FREQUENCY_NONE}) + @Retention(RetentionPolicy.SOURCE) + public @interface HyphenationFrequency {} + + /** + * Value for hyphenation frequency indicating no automatic hyphenation. Useful + * for backward compatibility, and for cases where the automatic hyphenation algorithm results + * in incorrect hyphenation. Mid-word breaks may still happen when a word is wider than the + * layout and there is otherwise no valid break. Soft hyphens are ignored and will not be used + * as suggestions for potential line breaks. + */ + public static final int HYPHENATION_FREQUENCY_NONE = 0; + + /** + * Value for hyphenation frequency indicating a light amount of automatic hyphenation, which + * is a conservative default. Useful for informal cases, such as short sentences or chat + * messages. + */ + public static final int HYPHENATION_FREQUENCY_NORMAL = 1; + + /** + * Value for hyphenation frequency indicating the full amount of automatic hyphenation, typical + * in typography. Useful for running text and where it's important to put the maximum amount of + * text in a screen with limited space. + */ + public static final int HYPHENATION_FREQUENCY_FULL = 2; + private static final ParagraphStyle[] NO_PARA_SPANS = ArrayUtils.emptyArray(ParagraphStyle.class); diff --git a/core/java/android/text/StaticLayout.java b/core/java/android/text/StaticLayout.java index 59c7c6d34eb8..d6d046be30a8 100644 --- a/core/java/android/text/StaticLayout.java +++ b/core/java/android/text/StaticLayout.java @@ -92,6 +92,7 @@ public class StaticLayout extends Layout { b.mEllipsize = null; b.mMaxLines = Integer.MAX_VALUE; b.mBreakStrategy = Layout.BREAK_STRATEGY_SIMPLE; + b.mHyphenationFrequency = Layout.HYPHENATION_FREQUENCY_NONE; b.mMeasuredText = MeasuredText.obtain(); return b; @@ -276,6 +277,19 @@ public class StaticLayout extends Layout { } /** + * Set hyphenation frequency, to control the amount of automatic hyphenation used. The + * default is {@link Layout#HYPHENATION_FREQUENCY_NONE}. + * + * @param hyphenationFrequency hyphenation frequency for the paragraph + * @return this builder, useful for chaining + * @see android.widget.TextView#setHyphenationFrequency + */ + public Builder setHyphenationFrequency(@HyphenationFrequency int hyphenationFrequency) { + mHyphenationFrequency = hyphenationFrequency; + return this; + } + + /** * Set indents. Arguments are arrays holding an indent amount, one per line, measured in * pixels. For lines past the last element in the array, the last element repeats. * @@ -302,7 +316,8 @@ public class StaticLayout extends Layout { * the native code is as follows. * * For each paragraph, do a nSetupParagraph, which sets paragraph text, line width, tab - * stops, break strategy (and possibly other parameters in the future). + * stops, break strategy, and hyphenation frequency (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) @@ -377,6 +392,7 @@ public class StaticLayout extends Layout { TextUtils.TruncateAt mEllipsize; int mMaxLines; int mBreakStrategy; + int mHyphenationFrequency; Paint.FontMetricsInt mFontMetricsInt = new Paint.FontMetricsInt(); @@ -644,7 +660,7 @@ public class StaticLayout extends Layout { nSetupParagraph(b.mNativePtr, chs, paraEnd - paraStart, firstWidth, firstWidthLineCount, restWidth, - variableTabStops, TAB_INCREMENT, b.mBreakStrategy); + variableTabStops, TAB_INCREMENT, b.mBreakStrategy, b.mHyphenationFrequency); // measurement has to be done before performing line breaking // but we don't want to recompute fontmetrics or span ranges the @@ -1153,7 +1169,7 @@ public class StaticLayout extends Layout { // 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, float firstWidth, int firstWidthLineCount, float restWidth, - int[] variableTabStops, int defaultTabStop, int breakStrategy); + int[] variableTabStops, int defaultTabStop, int breakStrategy, int hyphenationFrequency); private static native float nAddStyleRun(long nativePtr, long nativePaint, long nativeTypeface, int start, int end, boolean isRtl); diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java index 68c49cd06302..a98939289df2 100644 --- a/core/java/android/widget/TextView.java +++ b/core/java/android/widget/TextView.java @@ -238,6 +238,7 @@ import static android.os.Build.VERSION_CODES.JELLY_BEAN_MR1; * @attr ref android.R.styleable#TextView_letterSpacing * @attr ref android.R.styleable#TextView_fontFeatureSettings * @attr ref android.R.styleable#TextView_breakStrategy + * @attr ref android.R.styleable#TextView_hyphenationFrequency * @attr ref android.R.styleable#TextView_leftIndents * @attr ref android.R.styleable#TextView_rightIndents */ @@ -555,6 +556,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener private float mSpacingAdd = 0.0f; private int mBreakStrategy; + private int mHyphenationFrequency; private int[] mLeftIndents; private int[] mRightIndents; @@ -696,6 +698,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener float letterSpacing = 0; String fontFeatureSettings = null; mBreakStrategy = Layout.BREAK_STRATEGY_SIMPLE; + mHyphenationFrequency = Layout.HYPHENATION_FREQUENCY_NONE; final Resources.Theme theme = context.getTheme(); @@ -1154,6 +1157,10 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener mBreakStrategy = a.getInt(attr, Layout.BREAK_STRATEGY_SIMPLE); break; + case com.android.internal.R.styleable.TextView_hyphenationFrequency: + mHyphenationFrequency = a.getInt(attr, Layout.HYPHENATION_FREQUENCY_NONE); + break; + case com.android.internal.R.styleable.TextView_leftIndents: TypedArray margins = res.obtainTypedArray(a.getResourceId(attr, View.NO_ID)); mLeftIndents = parseDimensionArray(margins); @@ -3050,6 +3057,33 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener } /** + * Sets the hyphenation frequency. The default value for both TextView and EditText, which is set + * from the theme, is {@link Layout#HYPHENATION_FREQUENCY_NORMAL}. + * + * @attr ref android.R.styleable#TextView_hyphenationFrequency + * @see #getHyphenationFrequency() + */ + public void setHyphenationFrequency(@Layout.HyphenationFrequency int hyphenationFrequency) { + mHyphenationFrequency = hyphenationFrequency; + if (mLayout != null) { + nullLayouts(); + requestLayout(); + invalidate(); + } + } + + /** + * @return the currently set hyphenation frequency. + * + * @attr ref android.R.styleable#TextView_hyphenationFrequency + * @see #setHyphenationFrequency(int) + */ + @Layout.HyphenationFrequency + public int getHyphenationFrequency() { + return mHyphenationFrequency; + } + + /** * Set indents. Arguments are arrays holding an indent amount, one per line, measured in * pixels. For lines past the last element in the array, the last element repeats. * @@ -6637,7 +6671,8 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener .setTextDir(mTextDir) .setLineSpacing(mSpacingAdd, mSpacingMult) .setIncludePad(mIncludePad) - .setBreakStrategy(mBreakStrategy); + .setBreakStrategy(mBreakStrategy) + .setHyphenationFrequency(mHyphenationFrequency); if (mLeftIndents != null || mRightIndents != null) { builder.setIndents(mLeftIndents, mRightIndents); } @@ -6678,7 +6713,8 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener Layout result = null; if (mText instanceof Spannable) { result = new DynamicLayout(mText, mTransformed, mTextPaint, wantWidth, - alignment, mTextDir, mSpacingMult, mSpacingAdd, mIncludePad, mBreakStrategy, + alignment, mTextDir, mSpacingMult, mSpacingAdd, mIncludePad, + mBreakStrategy, mHyphenationFrequency, getKeyListener() == null ? effectiveEllipsize : null, ellipsisWidth); } else { if (boring == UNKNOWN_BORING) { @@ -6726,7 +6762,8 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener .setTextDir(mTextDir) .setLineSpacing(mSpacingAdd, mSpacingMult) .setIncludePad(mIncludePad) - .setBreakStrategy(mBreakStrategy); + .setBreakStrategy(mBreakStrategy) + .setHyphenationFrequency(mHyphenationFrequency); if (mLeftIndents != null || mRightIndents != null) { builder.setIndents(mLeftIndents, mRightIndents); } |
