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

Commit 8823c85f authored by Roozbeh Pournader's avatar Roozbeh Pournader
Browse files

Clean up TextUtils.doesNotNeedBidi()

One of the signatures of the method that used CharSequence was
unused. The other's implementation was too crude, resulting in too
many false negatives.

The new code now shares logic with BoringLayout in order to detect
potential bidi-affecting characters. The logic is intentionally
rough in order to be efficient: we still have false negatives, but
not as many as before.

Bug: 29254696
Change-Id: I106133369e93e49d7b2fe82ffc433e4556740ee8
parent ce9b1fa9
Loading
Loading
Loading
Loading
+1 −11
Original line number Original line Diff line number Diff line
@@ -247,17 +247,7 @@ public class BoringLayout extends Layout implements TextUtils.EllipsizeCallback
                final int len = end - start;
                final int len = end - start;
                for (int i = 0; i < len; i++) {
                for (int i = 0; i < len; i++) {
                    final char c = buffer[i];
                    final char c = buffer[i];

                    if (c == '\n' || c == '\t' || TextUtils.couldAffectRtl(c)) {
                    if (c == '\n' || c == '\t' ||
                            (c >= 0x0590 && c <= 0x08FF) ||  // RTL scripts
                            c == 0x200E ||  // Bidi format character
                            c == 0x200F ||  // Bidi format character
                            (c >= 0x202A && c <= 0x202E) ||  // Bidi format characters
                            (c >= 0x2066 && c <= 0x2069) ||  // Bidi format characters
                            (c >= 0xD800 && c <= 0xDFFF) ||  // surrogate pairs
                            (c >= 0xFB1D && c <= 0xFDFF) ||  // Hebrew and Arabic presentation forms
                            (c >= 0xFE70 && c <= 0xFEFE) // Arabic presentation forms
                       ) {
                        return true;
                        return true;
                    }
                    }
                }
                }
+21 −11
Original line number Original line Diff line number Diff line
@@ -1303,22 +1303,32 @@ public class TextUtils {
        return width;
        return width;
    }
    }


    private static final char FIRST_RIGHT_TO_LEFT = '\u0590';
    // Returns true if the character's presence could affect RTL layout.

    //
    // In order to be fast, the code is intentionally rough and quite conservative in its
    // considering inclusion of any non-BMP or surrogate characters or anything in the bidi
    // blocks or any bidi formatting characters with a potential to affect RTL layout.
    /* package */
    /* package */
    static boolean doesNotNeedBidi(CharSequence s, int start, int end) {
    static boolean couldAffectRtl(char c) {
        for (int i = start; i < end; i++) {
        return (0x0590 <= c && c <= 0x08FF) ||  // RTL scripts
            if (s.charAt(i) >= FIRST_RIGHT_TO_LEFT) {
                c == 0x200E ||  // Bidi format character
                return false;
                c == 0x200F ||  // Bidi format character
            }
                (0x202A <= c && c <= 0x202E) ||  // Bidi format characters
        }
                (0x2066 <= c && c <= 0x2069) ||  // Bidi format characters
        return true;
                (0xD800 <= c && c <= 0xDFFF) ||  // Surrogate pairs
    }
                (0xFB1D <= c && c <= 0xFDFF) ||  // Hebrew and Arabic presentation forms

                (0xFE70 <= c && c <= 0xFEFE);  // Arabic presentation forms
    }

    // Returns true if there is no character present that may potentially affect RTL layout.
    // Since this calls couldAffectRtl() above, it's also quite conservative, in the way that
    // it may return 'false' (needs bidi) although careful consideration may tell us it should
    // return 'true' (does not need bidi).
    /* package */
    /* package */
    static boolean doesNotNeedBidi(char[] text, int start, int len) {
    static boolean doesNotNeedBidi(char[] text, int start, int len) {
        for (int i = start, e = i + len; i < e; i++) {
        final int end = start + len;
            if (text[i] >= FIRST_RIGHT_TO_LEFT) {
        for (int i = start; i < end; i++) {
            if (couldAffectRtl(text[i])) {
                return false;
                return false;
            }
            }
        }
        }