Merge "Add line break word style parameter in the LineBreakConfig"

This commit is contained in:
James Lin
2022-01-24 17:27:12 +00:00
committed by Android (Google) Code Review
8 changed files with 175 additions and 21 deletions

View File

@@ -953,6 +953,7 @@ package android {
field public static final int letterSpacing = 16843958; // 0x10104b6
field public static final int level = 16844032; // 0x1010500
field public static final int lineBreakStyle = 16844365; // 0x101064d
field public static final int lineBreakWordStyle = 16844366; // 0x101064e
field public static final int lineHeight = 16844159; // 0x101057f
field public static final int lineSpacingExtra = 16843287; // 0x1010217
field public static final int lineSpacingMultiplier = 16843288; // 0x1010218
@@ -17618,12 +17619,16 @@ package android.graphics.text {
public final class LineBreakConfig {
ctor public LineBreakConfig();
method public int getLineBreakStyle();
method public void set(@Nullable android.graphics.text.LineBreakConfig);
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
field public static final int LINE_BREAK_STYLE_STRICT = 3; // 0x3
field public static final int LINE_BREAK_WORD_STYLE_NONE = 0; // 0x0
field public static final int LINE_BREAK_WORD_STYLE_PHRASE = 1; // 0x1
}
public class LineBreaker {

View File

@@ -363,6 +363,9 @@ public class PrecomputedText implements Spannable {
public String toString() {
int lineBreakStyle = (mLineBreakConfig != null)
? mLineBreakConfig.getLineBreakStyle() : LineBreakConfig.LINE_BREAK_STYLE_NONE;
int lineBreakWordStyle = (mLineBreakConfig != null)
? mLineBreakConfig.getLineBreakWordStyle()
: LineBreakConfig.LINE_BREAK_WORD_STYLE_NONE;
return "{"
+ "textSize=" + mPaint.getTextSize()
+ ", textScaleX=" + mPaint.getTextScaleX()
@@ -376,6 +379,7 @@ public class PrecomputedText implements Spannable {
+ ", breakStrategy=" + mBreakStrategy
+ ", hyphenationFrequency=" + mHyphenationFrequency
+ ", lineBreakStyle=" + lineBreakStyle
+ ", lineBreakWordStyle=" + lineBreakWordStyle
+ "}";
}
};

View File

@@ -350,6 +350,7 @@ import java.util.function.Supplier;
* @attr ref android.R.styleable#TextView_breakStrategy
* @attr ref android.R.styleable#TextView_hyphenationFrequency
* @attr ref android.R.styleable#TextView_lineBreakStyle
* @attr ref android.R.styleable#TextView_lineBreakWordStyle
* @attr ref android.R.styleable#TextView_autoSizeTextType
* @attr ref android.R.styleable#TextView_autoSizeMinTextSize
* @attr ref android.R.styleable#TextView_autoSizeMaxTextSize
@@ -461,6 +462,13 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
private static final int FLOATING_TOOLBAR_SELECT_ALL_REFRESH_DELAY = 500;
// The default value of the line break style.
private static final int DEFAULT_LINE_BREAK_STYLE = LineBreakConfig.LINE_BREAK_STYLE_NONE;
// The default value of the line break word style.
private static final int DEFAULT_LINE_BREAK_WORD_STYLE =
LineBreakConfig.LINE_BREAK_WORD_STYLE_NONE;
/**
* This change ID enables the fallback text line spacing (line height) for BoringLayout.
* @hide
@@ -1453,6 +1461,11 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
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));
break;
case com.android.internal.R.styleable.TextView_autoSizeTextType:
mAutoSizeTextType = a.getInt(attr, AUTO_SIZE_TEXT_TYPE_NONE);
break;
@@ -3985,6 +3998,10 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
float mLetterSpacing = 0;
String mFontFeatureSettings = null;
String mFontVariationSettings = null;
boolean mHasLineBreakStyle = false;
boolean mHasLineBreakWordStyle = false;
int mLineBreakStyle = DEFAULT_LINE_BREAK_STYLE;
int mLineBreakWordStyle = DEFAULT_LINE_BREAK_WORD_STYLE;
@Override
public String toString() {
@@ -4015,6 +4032,10 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
+ " mLetterSpacing:" + mLetterSpacing + "\n"
+ " mFontFeatureSettings:" + mFontFeatureSettings + "\n"
+ " mFontVariationSettings:" + mFontVariationSettings + "\n"
+ " mHasLineBreakStyle:" + mHasLineBreakStyle + "\n"
+ " mHasLineBreakWordStyle:" + mHasLineBreakWordStyle + "\n"
+ " mLineBreakStyle:" + mLineBreakStyle + "\n"
+ " mLineBreakWordStyle:" + mLineBreakWordStyle + "\n"
+ "}";
}
}
@@ -4062,6 +4083,10 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
com.android.internal.R.styleable.TextAppearance_fontFeatureSettings);
sAppearanceValues.put(com.android.internal.R.styleable.TextView_fontVariationSettings,
com.android.internal.R.styleable.TextAppearance_fontVariationSettings);
sAppearanceValues.put(com.android.internal.R.styleable.TextView_lineBreakStyle,
com.android.internal.R.styleable.TextAppearance_lineBreakStyle);
sAppearanceValues.put(com.android.internal.R.styleable.TextView_lineBreakWordStyle,
com.android.internal.R.styleable.TextAppearance_lineBreakWordStyle);
}
/**
@@ -4177,6 +4202,16 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
case com.android.internal.R.styleable.TextAppearance_fontVariationSettings:
attributes.mFontVariationSettings = appearance.getString(attr);
break;
case com.android.internal.R.styleable.TextAppearance_lineBreakStyle:
attributes.mHasLineBreakStyle = true;
attributes.mLineBreakStyle =
appearance.getInt(attr, attributes.mLineBreakStyle);
break;
case com.android.internal.R.styleable.TextAppearance_lineBreakWordStyle:
attributes.mHasLineBreakWordStyle = true;
attributes.mLineBreakWordStyle =
appearance.getInt(attr, attributes.mLineBreakWordStyle);
break;
default:
}
}
@@ -4242,8 +4277,45 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
if (attributes.mFontVariationSettings != null) {
setFontVariationSettings(attributes.mFontVariationSettings);
}
if (attributes.mHasLineBreakStyle || attributes.mHasLineBreakWordStyle) {
updateLineBreakConfigFromTextAppearance(attributes.mHasLineBreakStyle,
attributes.mHasLineBreakWordStyle, attributes.mLineBreakStyle,
attributes.mLineBreakWordStyle);
}
}
/**
* Updates the LineBreakConfig from the TextAppearance.
*
* This method updates the given line configuration from the TextAppearance. This method will
* request new layout if line break config has been changed.
*
* @param isLineBreakStyleSpecified true if the line break style is specified.
* @param isLineBreakWordStyleSpecified true if the line break word style is specified.
* @param lineBreakStyle the value of the line break style in the TextAppearance.
* @param lineBreakWordStyle the value of the line break word style in the TextAppearance.
*/
private void updateLineBreakConfigFromTextAppearance(boolean isLineBreakStyleSpecified,
boolean isLineBreakWordStyleSpecified,
@LineBreakConfig.LineBreakStyle int lineBreakStyle,
@LineBreakConfig.LineBreakWordStyle int lineBreakWordStyle) {
boolean updated = false;
if (isLineBreakStyleSpecified && mLineBreakConfig.getLineBreakStyle() != lineBreakStyle) {
mLineBreakConfig.setLineBreakStyle(lineBreakStyle);
updated = true;
}
if (isLineBreakWordStyleSpecified
&& mLineBreakConfig.getLineBreakWordStyle() != lineBreakWordStyle) {
mLineBreakConfig.setLineBreakWordStyle(lineBreakWordStyle);
updated = true;
}
if (updated && mLayout != null) {
nullLayouts();
requestLayout();
invalidate();
}
}
/**
* Get the default primary {@link Locale} of the text in this TextView. This will always be
* the first member of {@link #getTextLocales()}.
@@ -4800,18 +4872,29 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
/**
* Sets line break configuration indicates which strategy needs to be used when calculating the
* text wrapping. There are thee strategies for the line break style(lb):
* 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:
* {@link LineBreakConfig#LINE_BREAK_STYLE_LOOSE},
* {@link LineBreakConfig#LINE_BREAK_STYLE_NORMAL} and
* {@link LineBreakConfig#LINE_BREAK_STYLE_STRICT}.
* The default value of the line break style is {@link LineBreakConfig#LINE_BREAK_STYLE_NONE},
* which means no line break style is specified.
* 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">
* the line-break property</a>
*
* @param lineBreakConfig the line break config for text wrapping.
*/
public void setLineBreakConfig(@NonNull LineBreakConfig lineBreakConfig) {
Objects.requireNonNull(lineBreakConfig);
if (mLineBreakConfig.equals(lineBreakConfig)) {
return;
}
@@ -4858,7 +4941,13 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
mTextDir = params.getTextDirection();
mBreakStrategy = params.getBreakStrategy();
mHyphenationFrequency = params.getHyphenationFrequency();
mLineBreakConfig.set(params.getLineBreakConfig());
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);
}
if (mLayout != null) {
nullLayouts();
requestLayout();

View File

@@ -5038,6 +5038,10 @@
<attr name="fontFeatureSettings" format="string" />
<!-- Font variation settings. -->
<attr name="fontVariationSettings" format="string"/>
<!-- Specifies the strictness of line-breaking rules applied within an element. -->
<attr name="lineBreakStyle" />
<!-- Specifies the phrase-based breaking opportunities. -->
<attr name="lineBreakWordStyle" />
</declare-styleable>
<declare-styleable name="TextClock">
<!-- Specifies the formatting pattern used to show the time and/or date
@@ -5436,6 +5440,13 @@
<!-- ndicates 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.-->
<attr name="lineBreakWordStyle">
<!-- No line break word style specific. -->
<enum name="none" value="0" />
<!-- Specify the phrase based breaking. -->
<enum name="phrase" value="1" />
</attr>
<!-- Specify the type of auto-size. Note that this feature is not supported by EditText,
works only for TextView. -->
<attr name="autoSizeTextType" format="enum">

View File

@@ -3212,6 +3212,7 @@
<public type="attr" name="shouldUseDefaultUnfoldTransition" id="0x0101064c" />
<public type="attr" name="lineBreakStyle" id="0x0101064d" />
<public type="attr" name="lineBreakWordStyle" id="0x0101064e" />
<staging-public-group-final type="id" first-id="0x01fe0000">
<public name="accessibilityActionDragStart" />

View File

@@ -17,7 +17,7 @@
package android.graphics.text;
import android.annotation.IntDef;
import android.annotation.Nullable;
import android.annotation.NonNull;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@@ -58,7 +58,28 @@ public final class LineBreakConfig {
@Retention(RetentionPolicy.SOURCE)
public @interface LineBreakStyle {}
/**
* No line break word style specified.
*/
public static final int LINE_BREAK_WORD_STYLE_NONE = 0;
/**
* Indicates the line breaking is based on the phrased. This makes text wrapping only on
* meaningful words. The support of the text wrapping word style varies depending on the
* locales. If the locale does not support the phrase based text wrapping,
* there will be no effect.
*/
public static final int LINE_BREAK_WORD_STYLE_PHRASE = 1;
/** @hide */
@IntDef(prefix = { "LINE_BREAK_WORD_STYLE_" }, value = {
LINE_BREAK_WORD_STYLE_NONE, LINE_BREAK_WORD_STYLE_PHRASE
})
@Retention(RetentionPolicy.SOURCE)
public @interface LineBreakWordStyle {}
private @LineBreakStyle int mLineBreakStyle = LINE_BREAK_STYLE_NONE;
private @LineBreakWordStyle int mLineBreakWordStyle = LINE_BREAK_WORD_STYLE_NONE;
public LineBreakConfig() {
}
@@ -66,14 +87,12 @@ public final class LineBreakConfig {
/**
* Set the line break configuration.
*
* @param config the new line break configuration.
* @param lineBreakConfig the new line break configuration.
*/
public void set(@Nullable LineBreakConfig config) {
if (config != null) {
mLineBreakStyle = config.getLineBreakStyle();
} else {
mLineBreakStyle = LineBreakConfig.LINE_BREAK_STYLE_NONE;
}
public void set(@NonNull LineBreakConfig lineBreakConfig) {
Objects.requireNonNull(lineBreakConfig);
mLineBreakStyle = lineBreakConfig.getLineBreakStyle();
mLineBreakWordStyle = lineBreakConfig.getLineBreakWordStyle();
}
/**
@@ -94,17 +113,36 @@ public final class LineBreakConfig {
mLineBreakStyle = lineBreakStyle;
}
/**
* Get the line break word style.
*
* @return The current line break word style to be used for the text wrapping.
*/
public @LineBreakWordStyle int getLineBreakWordStyle() {
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;
if (this == o) return true;
if (!(o instanceof LineBreakConfig)) return false;
LineBreakConfig that = (LineBreakConfig) o;
return mLineBreakStyle == that.mLineBreakStyle;
return (mLineBreakStyle == that.mLineBreakStyle)
&& (mLineBreakWordStyle == that.mLineBreakWordStyle);
}
@Override
public int hashCode() {
return Objects.hash(mLineBreakStyle);
return Objects.hash(mLineBreakStyle, mLineBreakWordStyle);
}
}

View File

@@ -264,8 +264,10 @@ public class MeasuredText {
Preconditions.checkArgument(end <= mText.length, "Style exceeds the text length");
int lbStyle = (lineBreakConfig != null) ? lineBreakConfig.getLineBreakStyle() :
LineBreakConfig.LINE_BREAK_STYLE_NONE;
nAddStyleRun(mNativePtr, paint.getNativeInstance(), lbStyle, mCurrentOffset, end,
isRtl);
int lbWordStyle = (lineBreakConfig != null) ? lineBreakConfig.getLineBreakWordStyle() :
LineBreakConfig.LINE_BREAK_WORD_STYLE_NONE;
nAddStyleRun(mNativePtr, paint.getNativeInstance(), lbStyle, lbWordStyle,
mCurrentOffset, end, isRtl);
mCurrentOffset = end;
return this;
}
@@ -445,7 +447,8 @@ public class MeasuredText {
*
* @param nativeBuilderPtr The native MeasuredParagraph builder pointer.
* @param paintPtr The native paint pointer to be applied.
* @param lineBreakStyle The line break style of the text.
* @param lineBreakStyle The line break style(lb) of the text.
* @param lineBreakWordStyle The line break word style(lw) of the text.
* @param start The start offset in the copied buffer.
* @param end The end offset in the copied buffer.
* @param isRtl True if the text is RTL.
@@ -453,6 +456,7 @@ public class MeasuredText {
private static native void nAddStyleRun(/* Non Zero */ long nativeBuilderPtr,
/* Non Zero */ long paintPtr,
int lineBreakStyle,
int lineBreakWordStyle,
@IntRange(from = 0) int start,
@IntRange(from = 0) int end,
boolean isRtl);

View File

@@ -65,11 +65,13 @@ static jlong nInitBuilder(CRITICAL_JNI_PARAMS) {
// Regular JNI
static void nAddStyleRun(JNIEnv* /* unused */, jclass /* unused */, jlong builderPtr,
jlong paintPtr, jint lbStyle, jint start, jint end, jboolean isRtl) {
jlong paintPtr, jint lbStyle, jint lbWordStyle, jint start, jint end,
jboolean isRtl) {
Paint* paint = toPaint(paintPtr);
const Typeface* typeface = Typeface::resolveDefault(paint->getAndroidTypeface());
minikin::MinikinPaint minikinPaint = MinikinUtils::prepareMinikinPaint(paint, typeface);
toBuilder(builderPtr)->addStyleRun(start, end, std::move(minikinPaint), lbStyle, isRtl);
toBuilder(builderPtr)
->addStyleRun(start, end, std::move(minikinPaint), lbStyle, lbWordStyle, isRtl);
}
// Regular JNI
@@ -144,7 +146,7 @@ static jint nGetMemoryUsage(CRITICAL_JNI_PARAMS_COMMA jlong ptr) {
static const JNINativeMethod gMTBuilderMethods[] = {
// MeasuredParagraphBuilder native functions.
{"nInitBuilder", "()J", (void*)nInitBuilder},
{"nAddStyleRun", "(JJIIIZ)V", (void*)nAddStyleRun},
{"nAddStyleRun", "(JJIIIIZ)V", (void*)nAddStyleRun},
{"nAddReplacementRun", "(JJIIF)V", (void*)nAddReplacementRun},
{"nBuildMeasuredText", "(JJ[CZZZ)J", (void*)nBuildMeasuredText},
{"nFreeBuilder", "(J)V", (void*)nFreeBuilder},