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

Commit 941e5ffc authored by Eran Mizrahi's avatar Eran Mizrahi
Browse files

Bidi: Proper fix for mixing of RTL, LTR, number and puncation marks.

This fixes the following case, in which the previous behaviour was not satisfatory:
- Writting combinations of RTL text and punctuation marks. i.e typing "RTL 123 (456)" previously did not render correctly.
- The above also happened in most case where apps render the text. Striking examples are twitter (for example cases with numbers in parentheses in RTL text) and gallery apps where the number of pictures is appended at the end of the folder name (i.e. try a RTL folder name with a number at the end of its name in quickpic).
- Gmail app - fixed serious problems both with RTL sender names (any case where there is both an RTL sender name and a LTR one) and with subject lines containing combinations of RTL and LTR/numbers/puncation marks (for example subject "RTL (123)").

Also cleaned up a bit the logic and code of StaticLayout.java.

Change-Id: Iad6cbd21592ca70878d95134cb87b1d16bc365fa
parent 8543d04f
Loading
Loading
Loading
Loading
+24 −52
Original line number Diff line number Diff line
@@ -717,9 +717,6 @@ extends Layout
            byte prev = chInfo[j - 1];
            byte next = chInfo[j + 1];

            boolean isSpace = Character.isWhitespace(chs[j]);
            boolean nextIsSpace = Character.isWhitespace(chs[j + 1]);

            if (d == Character.DIRECTIONALITY_EUROPEAN_NUMBER_SEPARATOR) {
                if (prev == Character.DIRECTIONALITY_EUROPEAN_NUMBER &&
                    next == Character.DIRECTIONALITY_EUROPEAN_NUMBER)
@@ -731,27 +728,6 @@ extends Layout
                if (prev == Character.DIRECTIONALITY_ARABIC_NUMBER &&
                    next == Character.DIRECTIONALITY_ARABIC_NUMBER)
                    chInfo[j] = Character.DIRECTIONALITY_ARABIC_NUMBER;
                // add condition for spaces following the separator
                if (nextIsSpace &&
                            (   prev == Character.DIRECTIONALITY_EUROPEAN_NUMBER
                             || prev == Character.DIRECTIONALITY_ARABIC_NUMBER  ) )
                            chInfo[j] = SOR;
            }
            // add condition if the separator is a space
            else if (isSpace && prev != SOR &&
                            (   next == Character.DIRECTIONALITY_EUROPEAN_NUMBER
                             || next == Character.DIRECTIONALITY_ARABIC_NUMBER  ) ) {
                chInfo[j] = SOR;
                for (int k=j+1; k < n; ++k) {
                    if (chInfo[k] == Character.DIRECTIONALITY_LEFT_TO_RIGHT) {
                        chInfo[j] = Character.DIRECTIONALITY_LEFT_TO_RIGHT;
                        break;
                    }
                    if (chInfo[k] == Character.DIRECTIONALITY_RIGHT_TO_LEFT) {
                        chInfo[j] = Character.DIRECTIONALITY_RIGHT_TO_LEFT;
                        break;
                    }
                }
            }
        }

@@ -799,22 +775,6 @@ extends Layout

        // dump(chInfo, n, "W6");

        // W7 strong direction of european numbers
        cur = SOR;
        for (int j = 0; j < n; j++) {
            byte d = chInfo[j];

            if (d == SOR ||
                d == Character.DIRECTIONALITY_LEFT_TO_RIGHT ||
                d == Character.DIRECTIONALITY_RIGHT_TO_LEFT)
                cur = d;

            if (d == Character.DIRECTIONALITY_EUROPEAN_NUMBER)
                chInfo[j] = Character.DIRECTIONALITY_LEFT_TO_RIGHT;
        }

        // dump(chInfo, n, "W7");

        // N1, N2 neutrals
        cur = SOR;
        for (int j = 0; j < n; j++) {
@@ -825,7 +785,8 @@ extends Layout
                cur = d;
            } else if (d == Character.DIRECTIONALITY_EUROPEAN_NUMBER ||
                       d == Character.DIRECTIONALITY_ARABIC_NUMBER) {
                cur = Character.DIRECTIONALITY_LEFT_TO_RIGHT;
            } else if (cur == SOR) {
                chInfo[j] = cur;
            } else {
                byte dd = SOR;
                int k;
@@ -837,24 +798,35 @@ extends Layout
                        dd == Character.DIRECTIONALITY_RIGHT_TO_LEFT) {
                        break;
                    }
                    if (dd == Character.DIRECTIONALITY_EUROPEAN_NUMBER ||
                        dd == Character.DIRECTIONALITY_ARABIC_NUMBER) {
                        dd = Character.DIRECTIONALITY_LEFT_TO_RIGHT;
                        break;
                    }
                }

                for (int y = j; y < k; y++) {
                    if (dd == cur)
                        chInfo[y] = cur;
                    else
                        chInfo[y] = SOR;
                }
                if (dd != cur)
                    dd = SOR;

                for (int y = j; y < k; y++)
                    if (chInfo[y]!=Character.DIRECTIONALITY_EUROPEAN_NUMBER)
                        chInfo[y] = dd;

                j = k - 1;
            }
        }

        // dump(chInfo, n, "N12");

        // W7 strong direction of european numbers
        cur = SOR;
        for (int j = 0; j < n; j++) {
            byte d = chInfo[j];

            if (d == SOR ||
                d == Character.DIRECTIONALITY_LEFT_TO_RIGHT ||
                d == Character.DIRECTIONALITY_RIGHT_TO_LEFT)
                cur = d;

            if (d == Character.DIRECTIONALITY_EUROPEAN_NUMBER)
                chInfo[j] = Character.DIRECTIONALITY_LEFT_TO_RIGHT;
        }

        // dump(chInfo, n, "final");

        // extra: enforce that all tabs and surrogate characters go the
+3 −4
Original line number Diff line number Diff line
@@ -91,7 +91,7 @@ public class Styled
                if (TextUtils.hasRTLCharacters(text,start,end))
                    tmp = text.subSequence(start,end);
                else // otherwise we need to reverse it here:
                    tmp = TextUtils.getMirror(text, start, end);
                    tmp = TextUtils.getReverse(text, start, end);

                tmpstart = 0;
                // XXX: assumes getReverse doesn't change the length of the text
@@ -263,8 +263,7 @@ public class Styled
                if (TextUtils.hasRTLCharacters(text,start,end))
                    tmp = text.subSequence(start,end);
                else // otherwise we need to reverse it here:
                    tmp = TextUtils.getMirror(text, start, end);

                    tmp = TextUtils.getReverse(text, start, end);
                // XXX: this assumes getReverse doesn't tweak the length of
                // the text
                int tmpend = end - start;
+0 −45
Original line number Diff line number Diff line
@@ -534,51 +534,6 @@ public class TextUtils {
        private int mEnd;
    }

    /** @hide */
    public static CharSequence getMirror(CharSequence source,
                                          int start, int end) {
        return new Mirrorer(source, start, end);
    }

    private static class Mirrorer
    implements CharSequence, GetChars
    {
        public Mirrorer(CharSequence source, int start, int end) {
            mSource = source;
            mStart = start;
            mEnd = end;
        }

        public int length() {
            return mEnd - mStart;
        }

        public CharSequence subSequence(int start, int end) {
            char[] buf = new char[end - start];

            getChars(start, end, buf, 0);
            return new String(buf);
        }

        public String toString() {
            return subSequence(0, length()).toString();
        }

        public char charAt(int off) {
            return AndroidCharacter.getMirror(mSource.charAt(mEnd - 1 - off));
        }

        public void getChars(int start, int end, char[] dest, int destoff) {
            TextUtils.getChars(mSource, start + mStart, end + mStart,
                               dest, destoff);
            AndroidCharacter.mirror(dest, 0, end - start);
        }

        private CharSequence mSource;
        private int mStart;
        private int mEnd;
    }

    /** @hide */
    public static final int ALIGNMENT_SPAN = 1;
    /** @hide */
+2 −0
Original line number Diff line number Diff line
@@ -73,6 +73,8 @@ static jint reorderReshapeBidiText (JNIEnv* env, jclass c, jcharArray srcArray,

    UBiDi *para = ubidi_openSized(n, 0, &status);

    ubidi_setReorderingMode(para, UBIDI_REORDER_INVERSE_LIKE_DIRECT);

    jchar* src = env->GetCharArrayElements(srcArray, NULL);

    if (src != NULL && para != NULL && U_SUCCESS(status)) {