Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 6c9956e7 authored by Seigo Nonaka's avatar Seigo Nonaka
Browse files

Add NoHyphenationSpan and no hyphenation config into LineBreakConfig

NoHyphenationSpan is a specialized class of LineBreakConfigSpan
that disables hyphenation.

Bug: 283193586
Test: atest LineBreakTest
Change-Id: Ie77d345d83d871a5049ff713211a9dab116656b7
parent 0253bd2c
Loading
Loading
Loading
Loading
+10 −1
Original line number Diff line number Diff line
@@ -17653,9 +17653,13 @@ package android.graphics.pdf {
package android.graphics.text {
  public final class LineBreakConfig {
    method @FlaggedApi(FLAG_NO_BREAK_NO_HYPHENATION_SPAN) public int getHyphenation();
    method public int getLineBreakStyle();
    method public int getLineBreakWordStyle();
    method @NonNull public android.graphics.text.LineBreakConfig merge(@NonNull android.graphics.text.LineBreakConfig);
    field @FlaggedApi(FLAG_NO_BREAK_NO_HYPHENATION_SPAN) public static final int HYPHENATION_DISABLED = 0; // 0x0
    field @FlaggedApi(FLAG_NO_BREAK_NO_HYPHENATION_SPAN) public static final int HYPHENATION_ENABLED = 1; // 0x1
    field @FlaggedApi(FLAG_NO_BREAK_NO_HYPHENATION_SPAN) public static final int HYPHENATION_UNSPECIFIED = -1; // 0xffffffff
    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
@@ -17670,6 +17674,7 @@ package android.graphics.text {
    ctor public LineBreakConfig.Builder();
    method @NonNull public android.graphics.text.LineBreakConfig build();
    method @NonNull public android.graphics.text.LineBreakConfig.Builder merge(@NonNull android.graphics.text.LineBreakConfig);
    method @FlaggedApi(FLAG_NO_BREAK_NO_HYPHENATION_SPAN) @NonNull public android.graphics.text.LineBreakConfig.Builder setHyphenation(int);
    method @NonNull public android.graphics.text.LineBreakConfig.Builder setLineBreakStyle(int);
    method @NonNull public android.graphics.text.LineBreakConfig.Builder setLineBreakWordStyle(int);
  }
@@ -47875,11 +47880,15 @@ package android.text.style {
    method public void writeToParcel(@NonNull android.os.Parcel, int);
  }
  public class LineBreakConfigSpan {
  @FlaggedApi(FLAG_NO_BREAK_NO_HYPHENATION_SPAN) public class LineBreakConfigSpan {
    ctor public LineBreakConfigSpan(@NonNull android.graphics.text.LineBreakConfig);
    method @NonNull public android.graphics.text.LineBreakConfig getLineBreakConfig();
  }
  @FlaggedApi(FLAG_NO_BREAK_NO_HYPHENATION_SPAN) public static final class LineBreakConfigSpan.NoHyphenationSpan extends android.text.style.LineBreakConfigSpan {
    ctor @FlaggedApi(FLAG_NO_BREAK_NO_HYPHENATION_SPAN) public LineBreakConfigSpan.NoHyphenationSpan();
  }
  public interface LineHeightSpan extends android.text.style.ParagraphStyle android.text.style.WrapTogetherSpan {
    method public void chooseHeight(CharSequence, int, int, int, int, android.graphics.Paint.FontMetricsInt);
  }
+8 −0
Original line number Diff line number Diff line
package: "com.android.text.flags"

flag {
  name: "no_break_no_hyphenation_span"
  namespace: "text"
  description: "A feature flag that adding new spans that prevents line breaking and hyphenation."
  bug: "283193586"
}
+22 −0
Original line number Diff line number Diff line
@@ -16,6 +16,9 @@

package android.text.style;

import static com.android.text.flags.Flags.FLAG_NO_BREAK_NO_HYPHENATION_SPAN;

import android.annotation.FlaggedApi;
import android.annotation.NonNull;
import android.graphics.text.LineBreakConfig;

@@ -24,6 +27,7 @@ import java.util.Objects;
/**
 * LineBreakSpan for changing line break style of the specific region of the text.
 */
@FlaggedApi(FLAG_NO_BREAK_NO_HYPHENATION_SPAN)
public class LineBreakConfigSpan {
    private final LineBreakConfig mLineBreakConfig;

@@ -60,4 +64,22 @@ public class LineBreakConfigSpan {
    public String toString() {
        return "LineBreakConfigSpan{mLineBreakConfig=" + mLineBreakConfig + '}';
    }

    private static final LineBreakConfig sNoHyphenationConfig = new LineBreakConfig.Builder()
            .setHyphenation(LineBreakConfig.HYPHENATION_DISABLED)
            .build();

    /**
     * A specialized {@link LineBreakConfigSpan} that used for preventing hyphenation.
     */
    @FlaggedApi(FLAG_NO_BREAK_NO_HYPHENATION_SPAN)
    public static final class NoHyphenationSpan extends LineBreakConfigSpan {
        /**
         * Construct a new {@link NoHyphenationSpan}.
         */
        @FlaggedApi(FLAG_NO_BREAK_NO_HYPHENATION_SPAN)
        public NoHyphenationSpan() {
            super(sNoHyphenationConfig);
        }
    }
}
+131 −5
Original line number Diff line number Diff line
@@ -16,6 +16,9 @@

package android.graphics.text;

import static com.android.text.flags.Flags.FLAG_NO_BREAK_NO_HYPHENATION_SPAN;

import android.annotation.FlaggedApi;
import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
@@ -33,6 +36,56 @@ import java.util.Objects;
 */
public final class LineBreakConfig {

    /**
     * No hyphenation preference is specified.
     *
     * This is a special value of hyphenation preference indicating no hyphenation preference is
     * specified. When overriding a {@link LineBreakConfig} with another {@link LineBreakConfig}
     * with {@link Builder#merge(LineBreakConfig)} function, the hyphenation preference of
     * overridden config will be kept if the hyphenation preference of overriding config is
     * {@link #HYPHENATION_UNSPECIFIED}.
     *
     * <pre>
     *     val override = LineBreakConfig.Builder()
     *          .setLineBreakWordStyle(LineBreakConfig.LINE_BREAK_WORD_STYLE_PHRASE)
     *          .build();  // UNSPECIFIED if no setHyphenation is called.
     *     val config = LineBreakConfig.Builder()
     *          .setHyphenation(LineBreakConfig.HYPHENATION_DISABLED)
     *          .merge(override)
     *          .build()
     *     // Here, config has HYPHENATION_DISABLED for line break config and
     *     // LINE_BREAK_WORD_STYLE_PHRASE for line break word style.
     * </pre>
     *
     * This value is resolved to {@link #HYPHENATION_ENABLED} if this value is used for text
     * layout/rendering.
     */
    @FlaggedApi(FLAG_NO_BREAK_NO_HYPHENATION_SPAN)
    public static final int HYPHENATION_UNSPECIFIED = -1;

    /**
     * The hyphenation is disabled.
     */
    @FlaggedApi(FLAG_NO_BREAK_NO_HYPHENATION_SPAN)
    public static final int HYPHENATION_DISABLED = 0;

    /**
     * The hyphenation is enabled.
     *
     * Note: Even if the hyphenation is enabled with a line break strategy
     * {@link LineBreaker#BREAK_STRATEGY_SIMPLE}, the hyphenation will not be performed unless a
     * single word cannot meet width constraints.
     */
    @FlaggedApi(FLAG_NO_BREAK_NO_HYPHENATION_SPAN)
    public static final int HYPHENATION_ENABLED = 1;

    /** @hide */
    @IntDef(prefix = { "HYPHENATION_" }, value = {
            HYPHENATION_UNSPECIFIED, HYPHENATION_ENABLED, HYPHENATION_DISABLED,
    })
    @Retention(RetentionPolicy.SOURCE)
    public @interface Hyphenation {}

    /**
     * No line break style is specified.
     *
@@ -147,6 +200,8 @@ public final class LineBreakConfig {
        private @LineBreakWordStyle int mLineBreakWordStyle =
                LineBreakConfig.LINE_BREAK_WORD_STYLE_UNSPECIFIED;

        private @Hyphenation int mHyphenation = LineBreakConfig.HYPHENATION_UNSPECIFIED;

        /**
         * Builder constructor.
         */
@@ -188,6 +243,9 @@ public final class LineBreakConfig {
            if (config.mLineBreakWordStyle != LINE_BREAK_WORD_STYLE_UNSPECIFIED) {
                mLineBreakWordStyle = config.mLineBreakWordStyle;
            }
            if (config.mHyphenation != HYPHENATION_UNSPECIFIED) {
                mHyphenation = config.mHyphenation;
            }
            return this;
        }

@@ -201,9 +259,11 @@ public final class LineBreakConfig {
            if (config == null) {
                mLineBreakStyle = LINE_BREAK_STYLE_UNSPECIFIED;
                mLineBreakWordStyle = LINE_BREAK_WORD_STYLE_UNSPECIFIED;
                mHyphenation = HYPHENATION_UNSPECIFIED;
            } else {
                mLineBreakStyle = config.mLineBreakStyle;
                mLineBreakWordStyle = config.mLineBreakWordStyle;
                mHyphenation = config.mHyphenation;
            }
            return this;
        }
@@ -215,6 +275,11 @@ public final class LineBreakConfig {
         * {@link #LINE_BREAK_STYLE_UNSPECIFIED}, the line break style is reset to
         * {@link #LINE_BREAK_STYLE_UNSPECIFIED}.
         *
         * @see <a href="https://unicode.org/reports/tr35/#UnicodeLineBreakStyleIdentifier">
         *     Unicode Line Break Style Identifier</a>
         * @see <a href="https://drafts.csswg.org/css-text/#line-break-property">
         *     CSS Line Break Property</a>
         *
         * @param lineBreakStyle The new line-break style.
         * @return This {@code Builder}.
         */
@@ -230,6 +295,11 @@ public final class LineBreakConfig {
         * with {@link #LINE_BREAK_WORD_STYLE_UNSPECIFIED}, the line break style is reset to
         * {@link #LINE_BREAK_WORD_STYLE_UNSPECIFIED}.
         *
         * @see <a href="https://unicode.org/reports/tr35/#UnicodeLineBreakWordIdentifier">
         *     Unicode Line Break Word Identifier</a>
         * @see <a href="https://drafts.csswg.org/css-text/#word-break-property">
         *     CSS Word Break Property</a>
         *
         * @param lineBreakWordStyle The new line-break word style.
         * @return This {@code Builder}.
         */
@@ -238,6 +308,27 @@ public final class LineBreakConfig {
            return this;
        }

        /**
         * Sets the hyphenation preference
         *
         * Note: Even if the {@link LineBreakConfig#HYPHENATION_ENABLED} is specified, the
         * hyphenation will not be performed if the {@link android.widget.TextView} or underlying
         * {@link android.text.StaticLayout}, {@link LineBreaker} are configured with
         * {@link LineBreaker#HYPHENATION_FREQUENCY_NONE}.
         *
         * Note: Even if the hyphenation is enabled with a line break strategy
         * {@link LineBreaker#BREAK_STRATEGY_SIMPLE}, the hyphenation will not be performed unless a
         * single word cannot meet width constraints.
         *
         * @param hyphenation The hyphenation preference.
         * @return This {@code Builder}.
         */
        @FlaggedApi(FLAG_NO_BREAK_NO_HYPHENATION_SPAN)
        public @NonNull Builder setHyphenation(@Hyphenation int hyphenation) {
            mHyphenation = hyphenation;
            return this;
        }

        /**
         * Builds a {@link LineBreakConfig} instance.
         *
@@ -247,7 +338,7 @@ public final class LineBreakConfig {
         * @return The {@code LineBreakConfig} instance.
         */
        public @NonNull LineBreakConfig build() {
            return new LineBreakConfig(mLineBreakStyle, mLineBreakWordStyle);
            return new LineBreakConfig(mLineBreakStyle, mLineBreakWordStyle, mHyphenation);
        }
    }

@@ -275,6 +366,7 @@ public final class LineBreakConfig {

    private final @LineBreakStyle int mLineBreakStyle;
    private final @LineBreakWordStyle int mLineBreakWordStyle;
    private final @Hyphenation int mHyphenation;

    /**
     * Constructor with line-break parameters.
@@ -283,9 +375,11 @@ public final class LineBreakConfig {
     * {@code LineBreakConfig} instance.
     */
    private LineBreakConfig(@LineBreakStyle int lineBreakStyle,
            @LineBreakWordStyle int lineBreakWordStyle) {
            @LineBreakWordStyle int lineBreakWordStyle,
            @Hyphenation int hyphenation) {
        mLineBreakStyle = lineBreakStyle;
        mLineBreakWordStyle = lineBreakWordStyle;
        mHyphenation = hyphenation;
    }

    /**
@@ -339,6 +433,34 @@ public final class LineBreakConfig {
                ? LINE_BREAK_WORD_STYLE_NONE : config.mLineBreakWordStyle;
    }

    /**
     * Returns a hyphenation preference.
     *
     * @return A hyphenation preference.
     */
    @FlaggedApi(FLAG_NO_BREAK_NO_HYPHENATION_SPAN)
    public @Hyphenation  int getHyphenation() {
        return mHyphenation;
    }

    /**
     * Returns a hyphenation preference.
     *
     * This method never returns {@link #HYPHENATION_UNSPECIFIED}.
     *
     * @return A hyphenation preference.
     * @hide
     */
    public static @Hyphenation int getResolvedHyphenation(
            @Nullable LineBreakConfig config) {
        if (config == null) {
            return HYPHENATION_ENABLED;
        }
        return config.mHyphenation == HYPHENATION_UNSPECIFIED
                ? HYPHENATION_ENABLED : config.mHyphenation;
    }


    /**
     * Generates a new {@link LineBreakConfig} instance merged with given {@code config}.
     *
@@ -366,7 +488,9 @@ public final class LineBreakConfig {
                config.mLineBreakStyle == LINE_BREAK_STYLE_UNSPECIFIED
                        ? mLineBreakStyle : config.mLineBreakStyle,
                config.mLineBreakWordStyle == LINE_BREAK_WORD_STYLE_UNSPECIFIED
                        ? mLineBreakWordStyle : config.mLineBreakWordStyle);
                        ? mLineBreakWordStyle : config.mLineBreakWordStyle,
                config.mHyphenation == HYPHENATION_UNSPECIFIED
                        ? mHyphenation : config.mHyphenation);
    }

    @Override
@@ -376,12 +500,13 @@ public final class LineBreakConfig {
        if (!(o instanceof LineBreakConfig)) return false;
        LineBreakConfig that = (LineBreakConfig) o;
        return (mLineBreakStyle == that.mLineBreakStyle)
                && (mLineBreakWordStyle == that.mLineBreakWordStyle);
                && (mLineBreakWordStyle == that.mLineBreakWordStyle)
                && (mHyphenation == that.mHyphenation);
    }

    @Override
    public int hashCode() {
        return Objects.hash(mLineBreakStyle, mLineBreakWordStyle);
        return Objects.hash(mLineBreakStyle, mLineBreakWordStyle, mHyphenation);
    }

    @Override
@@ -389,6 +514,7 @@ public final class LineBreakConfig {
        return "LineBreakConfig{"
                + "mLineBreakStyle=" + mLineBreakStyle
                + ", mLineBreakWordStyle=" + mLineBreakWordStyle
                + ", mHyphenation= " + mHyphenation
                + '}';
    }
}
+4 −1
Original line number Diff line number Diff line
@@ -301,7 +301,9 @@ public class MeasuredText {
            Preconditions.checkArgument(end <= mText.length, "Style exceeds the text length");
            int lbStyle = LineBreakConfig.getResolvedLineBreakStyle(lineBreakConfig);
            int lbWordStyle = LineBreakConfig.getResolvedLineBreakWordStyle(lineBreakConfig);
            nAddStyleRun(mNativePtr, paint.getNativeInstance(), lbStyle, lbWordStyle,
            boolean hyphenation = LineBreakConfig.getResolvedHyphenation(lineBreakConfig)
                    == LineBreakConfig.HYPHENATION_ENABLED;
            nAddStyleRun(mNativePtr, paint.getNativeInstance(), lbStyle, lbWordStyle, hyphenation,
                    mCurrentOffset, end, isRtl);
            mCurrentOffset = end;

@@ -510,6 +512,7 @@ public class MeasuredText {
                                                /* Non Zero */ long paintPtr,
                                                int lineBreakStyle,
                                                int lineBreakWordStyle,
                                                boolean hyphenation,
                                                @IntRange(from = 0) int start,
                                                @IntRange(from = 0) int end,
                                                boolean isRtl);
Loading