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

Commit 8f502656 authored by Fabrice Di Meglio's avatar Fabrice Di Meglio
Browse files

Add charCount heuristic to TextView textDirection

- threshold set to 60% (using a constant)
- fix also one issue during layout direction resolution (parent could be null so delay resolution
up to when parent is no more null)

Change-Id: I65f24a297aac6bc0d5d482ee31b55db0b201e5bf
parent 22268868
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -22069,6 +22069,7 @@ package android.view {
    method public boolean willNotDraw();
    field public static android.util.Property ALPHA;
    field protected static int DEFAULT_TEXT_DIRECTION;
    field protected static float DEFAULT_TEXT_DIRECTION_CHAR_COUNT_THRESHOLD;
    field public static final int DRAWING_CACHE_QUALITY_AUTO = 0; // 0x0
    field public static final int DRAWING_CACHE_QUALITY_HIGH = 1048576; // 0x100000
    field public static final int DRAWING_CACHE_QUALITY_LOW = 524288; // 0x80000
+19 −3
Original line number Diff line number Diff line
@@ -2522,25 +2522,38 @@ public class View implements Drawable.Callback2, KeyEvent.Callback, Accessibilit
     */
    public static final int TEXT_DIRECTION_ANY_RTL = 2;

    /**
     * Text direction is the same as the one held by a 60% majority of the characters. If there is
     * no majority then the paragraph direction is the resolved layout direction of the View.
     *
     * @hide
     */
    public static final int TEXT_DIRECTION_CHAR_COUNT = 3;

    /**
     * Text direction is forced to LTR.
     *
     * @hide
     */
    public static final int TEXT_DIRECTION_LTR = 3;
    public static final int TEXT_DIRECTION_LTR = 4;

    /**
     * Text direction is forced to RTL.
     *
     * @hide
     */
    public static final int TEXT_DIRECTION_RTL = 4;
    public static final int TEXT_DIRECTION_RTL = 5;

    /**
     * Default text direction is inherited
     */
    protected static int DEFAULT_TEXT_DIRECTION = TEXT_DIRECTION_INHERIT;

    /**
     * Default threshold for "char count" heuristic.
     */
    protected static float DEFAULT_TEXT_DIRECTION_CHAR_COUNT_THRESHOLD = 0.6f;

    /**
     * The text direction that has been defined by {@link #setTextDirection(int)}.
     *
@@ -2551,6 +2564,7 @@ public class View implements Drawable.Callback2, KeyEvent.Callback, Accessibilit
            @ViewDebug.IntToString(from = TEXT_DIRECTION_INHERIT, to = "INHERIT"),
            @ViewDebug.IntToString(from = TEXT_DIRECTION_FIRST_STRONG, to = "FIRST_STRONG"),
            @ViewDebug.IntToString(from = TEXT_DIRECTION_ANY_RTL, to = "ANY_RTL"),
            @ViewDebug.IntToString(from = TEXT_DIRECTION_CHAR_COUNT, to = "CHAR_COUNT"),
            @ViewDebug.IntToString(from = TEXT_DIRECTION_LTR, to = "LTR"),
            @ViewDebug.IntToString(from = TEXT_DIRECTION_RTL, to = "RTL")
    })
@@ -11963,7 +11977,7 @@ public class View implements Drawable.Callback2, KeyEvent.Callback, Accessibilit
        mPrivateFlags |= FORCE_LAYOUT;
        mPrivateFlags |= INVALIDATED;

        if (mLayoutParams != null) {
        if (mLayoutParams != null && mParent != null) {
            mLayoutParams.resolveWithDirection(getResolvedLayoutDirection());
        }

@@ -12990,6 +13004,7 @@ public class View implements Drawable.Callback2, KeyEvent.Callback, Accessibilit
     * {@link #TEXT_DIRECTION_INHERIT},
     * {@link #TEXT_DIRECTION_FIRST_STRONG}
     * {@link #TEXT_DIRECTION_ANY_RTL},
     * {@link #TEXT_DIRECTION_CHAR_COUNT},
     * {@link #TEXT_DIRECTION_LTR},
     * {@link #TEXT_DIRECTION_RTL},
     *
@@ -13007,6 +13022,7 @@ public class View implements Drawable.Callback2, KeyEvent.Callback, Accessibilit
     * {@link #TEXT_DIRECTION_INHERIT},
     * {@link #TEXT_DIRECTION_FIRST_STRONG}
     * {@link #TEXT_DIRECTION_ANY_RTL},
     * {@link #TEXT_DIRECTION_CHAR_COUNT},
     * {@link #TEXT_DIRECTION_LTR},
     * {@link #TEXT_DIRECTION_RTL},
     *
+1 −0
Original line number Diff line number Diff line
@@ -5039,6 +5039,7 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
            // Pass down the hierarchy the following text direction values
            case TEXT_DIRECTION_FIRST_STRONG:
            case TEXT_DIRECTION_ANY_RTL:
            case TEXT_DIRECTION_CHAR_COUNT:
            case TEXT_DIRECTION_LTR:
            case TEXT_DIRECTION_RTL:
                resolvedTextDirection = mTextDirection;
+44 −0
Original line number Diff line number Diff line
@@ -10039,6 +10039,9 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
            case TEXT_DIRECTION_ANY_RTL:
                resolvedTextDirection = getTextDirectionFromAnyRtl(mText);
                break;
            case TEXT_DIRECTION_CHAR_COUNT:
                resolvedTextDirection = getTextDirectionFromCharCount(mText);
                break;
            case TEXT_DIRECTION_LTR:
                resolvedTextDirection = TEXT_DIRECTION_LTR;
                break;
@@ -10072,6 +10075,9 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
     */
    private static int getTextDirectionFromFirstStrong(final CharSequence cs) {
        final int length = cs.length();
        if (length == 0) {
            return TEXT_DIRECTION_UNDEFINED;
        }
        for(int i = 0; i < length; i++) {
            final char c = cs.charAt(i);
            final byte dir = Character.getDirectionality(c);
@@ -10094,6 +10100,9 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
     */
    private static int getTextDirectionFromAnyRtl(final CharSequence cs) {
        final int length = cs.length();
        if (length == 0) {
            return TEXT_DIRECTION_UNDEFINED;
        }
        boolean foundStrongLtr = false;
        boolean foundStrongRtl = false;
        for(int i = 0; i < length; i++) {
@@ -10114,6 +10123,41 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
        return TEXT_DIRECTION_UNDEFINED;
    }

    /**
     * Get text direction following the "char count" heuristic.
     *
     * @param cs the CharSequence used to get the text direction.
     *
     * @return {@link #TEXT_DIRECTION_RTL} if direction it RTL, {@link #TEXT_DIRECTION_LTR} if
     * direction it LTR or {@link #TEXT_DIRECTION_UNDEFINED} if direction cannot be found.
     */
    private int getTextDirectionFromCharCount(CharSequence cs) {
        final int length = cs.length();
        if (length == 0) {
            return TEXT_DIRECTION_UNDEFINED;
        }
        int countLtr = 0;
        int countRtl = 0;
        for(int i = 0; i < length; i++) {
            final char c = cs.charAt(i);
            final byte dir = Character.getDirectionality(c);
            if (isStrongLtrChar(dir)) {
                countLtr++;
            } else if (isStrongRtlChar(dir)) {
                countRtl++;
            }
        }
        final float percentLtr = ((float) countLtr) / (countLtr + countRtl);
        if (percentLtr > DEFAULT_TEXT_DIRECTION_CHAR_COUNT_THRESHOLD) {
            return TEXT_DIRECTION_LTR;
        }
        final float percentRtl = ((float) countRtl) / (countLtr + countRtl);
        if (percentRtl > DEFAULT_TEXT_DIRECTION_CHAR_COUNT_THRESHOLD) {
            return TEXT_DIRECTION_RTL;
        }
        return TEXT_DIRECTION_UNDEFINED;
    }

    /**
     * Return true if the char direction is corresponding to a "strong RTL char" following the
     * Unicode Bidirectional Algorithm (UBA).
+8 −4
Original line number Diff line number Diff line
@@ -1985,10 +1985,14 @@
                 it is LTR if it contains any strong LTR characters.  If there are neither, the
                 paragraph direction is the view’s resolved layout direction. -->
            <enum name="anyRtl" value="2" />
            <!-- The text direction is left to right. -->
            <enum name="ltr" value="3" />
            <!-- The text direction is right to left. -->
            <enum name="rtl" value="4" />
            <!-- The paragraph direction is the same as the one held by a 60% majority of the
                 characters. If there is no majority then the paragraph direction is the resolved
                 layout direction of the View. -->
            <enum name="charCount" value="3" />
            <!-- The paragraph direction is left to right. -->
            <enum name="ltr" value="4" />
            <!-- The paragraph direction is right to left. -->
            <enum name="rtl" value="5" />
        </attr>
    </declare-styleable>

Loading