Merge "Update the text wrapping API." into tm-dev

This commit is contained in:
TreeHugger Robot
2022-03-14 23:09:41 +00:00
committed by Android (Google) Code Review
6 changed files with 180 additions and 125 deletions

View File

@@ -16407,12 +16407,8 @@ package android.graphics.pdf {
package android.graphics.text {
public final class LineBreakConfig {
ctor public LineBreakConfig();
method public int getLineBreakStyle();
method public int getLineBreakWordStyle();
method public void set(@NonNull android.graphics.text.LineBreakConfig);
method public void setLineBreakStyle(int);
method public void setLineBreakWordStyle(int);
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
@@ -16421,6 +16417,13 @@ package android.graphics.text {
field public static final int LINE_BREAK_WORD_STYLE_PHRASE = 1; // 0x1
}
public static final class LineBreakConfig.Builder {
ctor public LineBreakConfig.Builder();
method @NonNull public android.graphics.text.LineBreakConfig build();
method @NonNull public android.graphics.text.LineBreakConfig.Builder setLineBreakStyle(int);
method @NonNull public android.graphics.text.LineBreakConfig.Builder setLineBreakWordStyle(int);
}
public class LineBreaker {
method @NonNull public android.graphics.text.LineBreaker.Result computeLineBreaks(@NonNull android.graphics.text.MeasuredText, @NonNull android.graphics.text.LineBreaker.ParagraphConstraints, @IntRange(from=0) int);
field public static final int BREAK_STRATEGY_BALANCED = 2; // 0x2
@@ -45062,7 +45065,7 @@ package android.text {
public static final class PrecomputedText.Params {
method public int getBreakStrategy();
method public int getHyphenationFrequency();
method @Nullable public android.graphics.text.LineBreakConfig getLineBreakConfig();
method @NonNull public android.graphics.text.LineBreakConfig getLineBreakConfig();
method @NonNull public android.text.TextDirectionHeuristic getTextDirection();
method @NonNull public android.text.TextPaint getTextPaint();
}
@@ -57352,7 +57355,8 @@ package android.widget {
method public final android.text.Layout getLayout();
method public float getLetterSpacing();
method public int getLineBounds(int, android.graphics.Rect);
method @NonNull public android.graphics.text.LineBreakConfig getLineBreakConfig();
method public int getLineBreakStyle();
method public int getLineBreakWordStyle();
method public int getLineCount();
method public int getLineHeight();
method public float getLineSpacingExtra();
@@ -57480,7 +57484,8 @@ package android.widget {
method public void setKeyListener(android.text.method.KeyListener);
method public void setLastBaselineToBottomHeight(@IntRange(from=0) @Px int);
method public void setLetterSpacing(float);
method public void setLineBreakConfig(@NonNull android.graphics.text.LineBreakConfig);
method public void setLineBreakStyle(int);
method public void setLineBreakWordStyle(int);
method public void setLineHeight(@IntRange(from=0) @Px int);
method public void setLineSpacing(float, float);
method public void setLines(int);

View File

@@ -99,7 +99,7 @@ public class PrecomputedText implements Spannable {
private final @Layout.HyphenationFrequency int mHyphenationFrequency;
// The line break configuration for calculating text wrapping.
private final @Nullable LineBreakConfig mLineBreakConfig;
private final @NonNull LineBreakConfig mLineBreakConfig;
/**
* A builder for creating {@link Params}.
@@ -119,7 +119,7 @@ public class PrecomputedText implements Spannable {
Layout.HYPHENATION_FREQUENCY_NORMAL;
// The line break configuration for calculating text wrapping.
private @Nullable LineBreakConfig mLineBreakConfig;
private @NonNull LineBreakConfig mLineBreakConfig = LineBreakConfig.NONE;
/**
* Builder constructor.
@@ -212,7 +212,7 @@ public class PrecomputedText implements Spannable {
// For the external developers, use Builder instead.
/** @hide */
public Params(@NonNull TextPaint paint,
@Nullable LineBreakConfig lineBreakConfig,
@NonNull LineBreakConfig lineBreakConfig,
@NonNull TextDirectionHeuristic textDir,
@Layout.BreakStrategy int strategy,
@Layout.HyphenationFrequency int frequency) {
@@ -260,11 +260,12 @@ public class PrecomputedText implements Spannable {
}
/**
* Return the line break configuration for this text.
* Returns the {@link LineBreakConfig} for this text.
*
* @return the current line break configuration, null if no line break configuration is set.
* @return the current line break configuration. The {@link LineBreakConfig} with default
* values will be returned if no line break configuration is set.
*/
public @Nullable LineBreakConfig getLineBreakConfig() {
public @NonNull LineBreakConfig getLineBreakConfig() {
return mLineBreakConfig;
}
@@ -297,9 +298,9 @@ public class PrecomputedText implements Spannable {
/** @hide */
public @CheckResultUsableResult int checkResultUsable(@NonNull TextPaint paint,
@NonNull TextDirectionHeuristic textDir, @Layout.BreakStrategy int strategy,
@Layout.HyphenationFrequency int frequency, @Nullable LineBreakConfig lbConfig) {
@Layout.HyphenationFrequency int frequency, @NonNull LineBreakConfig lbConfig) {
if (mBreakStrategy == strategy && mHyphenationFrequency == frequency
&& isLineBreakEquals(mLineBreakConfig, lbConfig)
&& mLineBreakConfig.equals(lbConfig)
&& mPaint.equalsForTextMeasurement(paint)) {
return mTextDir == textDir ? USABLE : NEED_RECOMPUTE;
} else {
@@ -307,29 +308,6 @@ public class PrecomputedText implements Spannable {
}
}
/**
* Check the two LineBreakConfig instances are equal.
* This method assumes they are equal if one parameter is null and the other parameter has
* a LineBreakStyle value of LineBreakConfig.LINE_BREAK_STYLE_NONE.
*
* @param o1 the first LineBreakConfig instance.
* @param o2 the second LineBreakConfig instance.
* @return true if the two LineBreakConfig instances are equal.
*/
private boolean isLineBreakEquals(LineBreakConfig o1, LineBreakConfig o2) {
if (Objects.equals(o1, o2)) {
return true;
}
if (o1 == null && (o2 != null
&& o2.getLineBreakStyle() == LineBreakConfig.LINE_BREAK_STYLE_NONE)) {
return true;
} else if (o2 == null && (o1 != null
&& o1.getLineBreakStyle() == LineBreakConfig.LINE_BREAK_STYLE_NONE)) {
return true;
}
return false;
}
/**
* Check if the same text layout.
*

View File

@@ -112,6 +112,7 @@ public class StaticLayout extends Layout {
b.mBreakStrategy = Layout.BREAK_STRATEGY_SIMPLE;
b.mHyphenationFrequency = Layout.HYPHENATION_FREQUENCY_NONE;
b.mJustificationMode = Layout.JUSTIFICATION_MODE_NONE;
b.mLineBreakConfig = LineBreakConfig.NONE;
return b;
}
@@ -410,7 +411,8 @@ public class StaticLayout extends Layout {
*
* @param lineBreakConfig the line break configuration for text wrapping.
* @return this builder, useful for chaining.
* @see android.widget.TextView#setLineBreakConfig
* @see android.widget.TextView#setLineBreakStyle
* @see android.widget.TextView#setLineBreakWordStyle
*/
@NonNull
public Builder setLineBreakConfig(@NonNull LineBreakConfig lineBreakConfig) {
@@ -454,7 +456,7 @@ public class StaticLayout extends Layout {
@Nullable private int[] mRightIndents;
private int mJustificationMode;
private boolean mAddLastLineLineSpacing;
private LineBreakConfig mLineBreakConfig;
private LineBreakConfig mLineBreakConfig = LineBreakConfig.NONE;
private final Paint.FontMetricsInt mFontMetricsInt = new Paint.FontMetricsInt();

View File

@@ -788,7 +788,8 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
private Layout mLayout;
private boolean mLocalesChanged = false;
private int mTextSizeUnit = -1;
private LineBreakConfig mLineBreakConfig = new LineBreakConfig();
private int mLineBreakStyle = DEFAULT_LINE_BREAK_STYLE;
private int mLineBreakWordStyle = DEFAULT_LINE_BREAK_WORD_STYLE;
// This is used to reflect the current user preference for changing font weight and making text
// more bold.
@@ -1457,13 +1458,12 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
break;
case com.android.internal.R.styleable.TextView_lineBreakStyle:
mLineBreakConfig.setLineBreakStyle(
a.getInt(attr, LineBreakConfig.LINE_BREAK_STYLE_NONE));
mLineBreakStyle = a.getInt(attr, LineBreakConfig.LINE_BREAK_STYLE_NONE);
break;
case com.android.internal.R.styleable.TextView_lineBreakWordStyle:
mLineBreakConfig.setLineBreakWordStyle(
a.getInt(attr, LineBreakConfig.LINE_BREAK_WORD_STYLE_NONE));
mLineBreakWordStyle = a.getInt(attr,
LineBreakConfig.LINE_BREAK_WORD_STYLE_NONE);
break;
case com.android.internal.R.styleable.TextView_autoSizeTextType:
@@ -4301,13 +4301,12 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
@LineBreakConfig.LineBreakStyle int lineBreakStyle,
@LineBreakConfig.LineBreakWordStyle int lineBreakWordStyle) {
boolean updated = false;
if (isLineBreakStyleSpecified && mLineBreakConfig.getLineBreakStyle() != lineBreakStyle) {
mLineBreakConfig.setLineBreakStyle(lineBreakStyle);
if (isLineBreakStyleSpecified && mLineBreakStyle != lineBreakStyle) {
mLineBreakStyle = lineBreakStyle;
updated = true;
}
if (isLineBreakWordStyleSpecified
&& mLineBreakConfig.getLineBreakWordStyle() != lineBreakWordStyle) {
mLineBreakConfig.setLineBreakWordStyle(lineBreakWordStyle);
if (isLineBreakWordStyleSpecified && mLineBreakWordStyle != lineBreakWordStyle) {
mLineBreakWordStyle = lineBreakWordStyle;
updated = true;
}
if (updated && mLayout != null) {
@@ -4871,50 +4870,72 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
}
/**
* Sets line break configuration indicates which strategy needs to be used when calculating the
* text wrapping.
* <P>
* There are two types of line break rules that can be configured at the same time. One is
* line break style(lb) and the other is line break word style(lw). The line break style
* affects rule-based breaking. The line break word style affects dictionary-based breaking
* and provide phrase-based breaking opportunities. There are several types for the
* line break style:
* Set the line break style for text wrapping.
*
* The line break style to indicates the line break strategies can be used when
* calculating the text wrapping. The line break style affects rule-based breaking. It
* specifies the strictness of line-breaking rules.
* There are several types for the line break style:
* {@link LineBreakConfig#LINE_BREAK_STYLE_LOOSE},
* {@link LineBreakConfig#LINE_BREAK_STYLE_NORMAL} and
* {@link LineBreakConfig#LINE_BREAK_STYLE_STRICT}.
* The type for the line break word style is
* {@link LineBreakConfig#LINE_BREAK_WORD_STYLE_PHRASE}.
* The default values of the line break style and the line break word style are
* {@link LineBreakConfig#LINE_BREAK_STYLE_NONE} and
* {@link LineBreakConfig#LINE_BREAK_WORD_STYLE_NONE} respectively, indicating that no line
* breaking rules are specified.
* See <a href="https://drafts.csswg.org/css-text/#line-break-property">
* {@link LineBreakConfig#LINE_BREAK_STYLE_STRICT}. The default values of the line break style
* is {@link LineBreakConfig#LINE_BREAK_STYLE_NONE}, indicating no breaking rule is specified.
* See <a href="https://www.w3.org/TR/css-text-3/#line-break-property">
* the line-break property</a>
*
* @param lineBreakConfig the line break config for text wrapping.
* @param lineBreakStyle the line break style for the text.
*/
public void setLineBreakConfig(@NonNull LineBreakConfig lineBreakConfig) {
Objects.requireNonNull(lineBreakConfig);
if (mLineBreakConfig.equals(lineBreakConfig)) {
return;
}
mLineBreakConfig.set(lineBreakConfig);
if (mLayout != null) {
nullLayouts();
requestLayout();
invalidate();
public void setLineBreakStyle(@LineBreakConfig.LineBreakStyle int lineBreakStyle) {
if (mLineBreakStyle != lineBreakStyle) {
mLineBreakStyle = lineBreakStyle;
if (mLayout != null) {
nullLayouts();
requestLayout();
invalidate();
}
}
}
/**
* Get the current line break configuration for text wrapping.
* Set the line break word style for text wrapping.
*
* @return the current line break configuration to be used for text wrapping.
* The line break word style affects dictionary-based breaking and provide phrase-based
* breaking opportunities. The type for the line break word style is
* {@link LineBreakConfig#LINE_BREAK_WORD_STYLE_PHRASE}. The default values of the line break
* word style is {@link LineBreakConfig#LINE_BREAK_WORD_STYLE_NONE}, indicating no breaking rule
* is specified.
* See <a href="https://www.w3.org/TR/css-text-3/#word-break-property">
* the word-break property</a>
*
* @param lineBreakWordStyle the line break word style for the tet
*/
public @NonNull LineBreakConfig getLineBreakConfig() {
LineBreakConfig lbConfig = new LineBreakConfig();
lbConfig.set(mLineBreakConfig);
return lbConfig;
public void setLineBreakWordStyle(@LineBreakConfig.LineBreakWordStyle int lineBreakWordStyle) {
if (mLineBreakWordStyle != lineBreakWordStyle) {
mLineBreakWordStyle = lineBreakWordStyle;
if (mLayout != null) {
nullLayouts();
requestLayout();
invalidate();
}
}
}
/**
* Get the current line break style for text wrapping.
*
* @return the current line break style to be used for text wrapping.
*/
public @LineBreakConfig.LineBreakStyle int getLineBreakStyle() {
return mLineBreakStyle;
}
/**
* Get the current line word break style for text wrapping.
*
* @return the current line break word style to be used for text wrapping.
*/
public @LineBreakConfig.LineBreakWordStyle int getLineBreakWordStyle() {
return mLineBreakWordStyle;
}
/**
@@ -4924,7 +4945,8 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
* @see PrecomputedText
*/
public @NonNull PrecomputedText.Params getTextMetricsParams() {
return new PrecomputedText.Params(new TextPaint(mTextPaint), mLineBreakConfig,
return new PrecomputedText.Params(new TextPaint(mTextPaint),
LineBreakConfig.getLineBreakConfig(mLineBreakStyle, mLineBreakWordStyle),
getTextDirectionHeuristic(),
mBreakStrategy, mHyphenationFrequency);
}
@@ -4941,13 +4963,9 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
mTextDir = params.getTextDirection();
mBreakStrategy = params.getBreakStrategy();
mHyphenationFrequency = params.getHyphenationFrequency();
if (params.getLineBreakConfig() != null) {
mLineBreakConfig.set(params.getLineBreakConfig());
} else {
// Set default value if the line break config in the PrecomputedText.Params is null.
mLineBreakConfig.setLineBreakStyle(DEFAULT_LINE_BREAK_STYLE);
mLineBreakConfig.setLineBreakWordStyle(DEFAULT_LINE_BREAK_WORD_STYLE);
}
LineBreakConfig lineBreakConfig = params.getLineBreakConfig();
mLineBreakStyle = lineBreakConfig.getLineBreakStyle();
mLineBreakWordStyle = lineBreakConfig.getLineBreakWordStyle();
if (mLayout != null) {
nullLayouts();
requestLayout();
@@ -6486,7 +6504,8 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
}
final @PrecomputedText.Params.CheckResultUsableResult int checkResult =
precomputed.getParams().checkResultUsable(getPaint(), mTextDir, mBreakStrategy,
mHyphenationFrequency, mLineBreakConfig);
mHyphenationFrequency, LineBreakConfig.getLineBreakConfig(
mLineBreakStyle, mLineBreakWordStyle));
switch (checkResult) {
case PrecomputedText.Params.UNUSABLE:
throw new IllegalArgumentException(
@@ -9383,7 +9402,8 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
.setHyphenationFrequency(mHyphenationFrequency)
.setJustificationMode(mJustificationMode)
.setMaxLines(mMaxMode == LINES ? mMaximum : Integer.MAX_VALUE)
.setLineBreakConfig(mLineBreakConfig);
.setLineBreakConfig(LineBreakConfig.getLineBreakConfig(
mLineBreakStyle, mLineBreakWordStyle));
if (shouldEllipsize) {
builder.setEllipsize(mEllipsize)
.setEllipsizedWidth(ellipsisWidth);
@@ -9498,7 +9518,8 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
.setHyphenationFrequency(mHyphenationFrequency)
.setJustificationMode(mJustificationMode)
.setMaxLines(mMaxMode == LINES ? mMaximum : Integer.MAX_VALUE)
.setLineBreakConfig(mLineBreakConfig);
.setLineBreakConfig(LineBreakConfig.getLineBreakConfig(
mLineBreakStyle, mLineBreakWordStyle));
if (shouldEllipsize) {
builder.setEllipsize(effectiveEllipsize)
.setEllipsizedWidth(ellipsisWidth);
@@ -9866,7 +9887,8 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
.setJustificationMode(getJustificationMode())
.setMaxLines(mMaxMode == LINES ? mMaximum : Integer.MAX_VALUE)
.setTextDirection(getTextDirectionHeuristic())
.setLineBreakConfig(mLineBreakConfig);
.setLineBreakConfig(LineBreakConfig.getLineBreakConfig(
mLineBreakStyle, mLineBreakWordStyle));
final StaticLayout layout = layoutBuilder.build();

View File

@@ -5479,9 +5479,9 @@
<enum name="none" value="0" />
<!-- Use the least restrictive rule for line-breaking. -->
<enum name="loose" value="1" />
<!-- Indicate breaking text with the most comment set of line-breaking rules. -->
<!-- Indicates breaking text with the most comment set of line-breaking rules. -->
<enum name="normal" value="2" />
<!-- ndicates breaking text with the most strictest line-breaking rules. -->
<!-- Indicates breaking text with the most strictest line-breaking rules. -->
<enum name="strict" value="3" />
</attr>
<!-- Specify the phrase-based line break can be used when calculating the text wrapping.-->

View File

@@ -26,7 +26,7 @@ import java.util.Objects;
/**
* Indicates the strategies can be used when calculating the text wrapping.
*
* See <a href="https://drafts.csswg.org/css-text/#line-break-property">the line-break property</a>
* See <a href="https://www.w3.org/TR/css-text-3/#line-break-property">the line-break property</a>
*/
public final class LineBreakConfig {
@@ -78,21 +78,87 @@ public final class LineBreakConfig {
@Retention(RetentionPolicy.SOURCE)
public @interface LineBreakWordStyle {}
private @LineBreakStyle int mLineBreakStyle = LINE_BREAK_STYLE_NONE;
private @LineBreakWordStyle int mLineBreakWordStyle = LINE_BREAK_WORD_STYLE_NONE;
/**
* A builder for creating {@link LineBreakConfig}.
*/
public static final class Builder {
// The line break style for the LineBreakConfig.
private @LineBreakStyle int mLineBreakStyle = LineBreakConfig.LINE_BREAK_STYLE_NONE;
public LineBreakConfig() {
// The line break word style for the LineBreakConfig.
private @LineBreakWordStyle int mLineBreakWordStyle =
LineBreakConfig.LINE_BREAK_WORD_STYLE_NONE;
/**
* Builder constructor with line break parameters.
*/
public Builder() {
}
/**
* Set the line break style.
*
* @param lineBreakStyle the new line break style.
* @return this Builder
*/
public @NonNull Builder setLineBreakStyle(@LineBreakStyle int lineBreakStyle) {
mLineBreakStyle = lineBreakStyle;
return this;
}
/**
* Set the line break word style.
*
* @param lineBreakWordStyle the new line break word style.
* @return this Builder
*/
public @NonNull Builder setLineBreakWordStyle(@LineBreakWordStyle int lineBreakWordStyle) {
mLineBreakWordStyle = lineBreakWordStyle;
return this;
}
/**
* Build the {@link LineBreakConfig}
*
* @return the LineBreakConfig instance.
*/
public @NonNull LineBreakConfig build() {
return new LineBreakConfig(mLineBreakStyle, mLineBreakWordStyle);
}
}
/**
* Set the line break configuration.
* Create the LineBreakConfig instance.
*
* @param lineBreakConfig the new line break configuration.
* @param lineBreakStyle the line break style for text wrapping.
* @param lineBreakWordStyle the line break word style for text wrapping.
* @return the {@link LineBreakConfig} instance.
* @hide
*/
public void set(@NonNull LineBreakConfig lineBreakConfig) {
Objects.requireNonNull(lineBreakConfig);
mLineBreakStyle = lineBreakConfig.getLineBreakStyle();
mLineBreakWordStyle = lineBreakConfig.getLineBreakWordStyle();
public static @NonNull LineBreakConfig getLineBreakConfig(@LineBreakStyle int lineBreakStyle,
@LineBreakWordStyle int lineBreakWordStyle) {
LineBreakConfig.Builder builder = new LineBreakConfig.Builder();
return builder.setLineBreakStyle(lineBreakStyle)
.setLineBreakWordStyle(lineBreakWordStyle)
.build();
}
/** @hide */
public static final LineBreakConfig NONE =
new Builder().setLineBreakStyle(LINE_BREAK_STYLE_NONE)
.setLineBreakWordStyle(LINE_BREAK_WORD_STYLE_NONE).build();
private final @LineBreakStyle int mLineBreakStyle;
private final @LineBreakWordStyle int mLineBreakWordStyle;
/**
* Constructor with the line break parameters.
* Use the {@link LineBreakConfig.Builder} to create the LineBreakConfig instance.
*/
private LineBreakConfig(@LineBreakStyle int lineBreakStyle,
@LineBreakWordStyle int lineBreakWordStyle) {
mLineBreakStyle = lineBreakStyle;
mLineBreakWordStyle = lineBreakWordStyle;
}
/**
@@ -104,15 +170,6 @@ public final class LineBreakConfig {
return mLineBreakStyle;
}
/**
* Set the line break style.
*
* @param lineBreakStyle the new line break style.
*/
public void setLineBreakStyle(@LineBreakStyle int lineBreakStyle) {
mLineBreakStyle = lineBreakStyle;
}
/**
* Get the line break word style.
*
@@ -122,15 +179,6 @@ public final class LineBreakConfig {
return mLineBreakWordStyle;
}
/**
* Set the line break word style.
*
* @param lineBreakWordStyle the new line break word style.
*/
public void setLineBreakWordStyle(@LineBreakWordStyle int lineBreakWordStyle) {
mLineBreakWordStyle = lineBreakWordStyle;
}
@Override
public boolean equals(Object o) {
if (o == null) return false;