summaryrefslogtreecommitdiff
path: root/core/java
diff options
context:
space:
mode:
authorRoozbeh Pournader <roozbeh@google.com>2015-05-12 12:01:06 -0700
committerRoozbeh Pournader <roozbeh@google.com>2015-05-12 14:56:57 -0700
commit95c7a13f2ac4f31ed3aaec9b47b9a29a3dbca978 (patch)
tree9fc3e976118f16aab4dd5279e84e6eb117b4f3f8 /core/java
parentd2c05188b669256ab9d6024ad5793e0ca891fed0 (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.java10
-rw-r--r--core/java/android/text/Layout.java29
-rw-r--r--core/java/android/text/StaticLayout.java22
-rw-r--r--core/java/android/widget/TextView.java43
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);
}