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

Commit c0dc4062 authored by Gilles Debunne's avatar Gilles Debunne Committed by Android (Google) Code Review
Browse files

Merge "Added support for Unicode surrogate characters in word selection" into honeycomb

parents 660733d3 79ff914f
Loading
Loading
Loading
Loading
+16 −21
Original line number Diff line number Diff line
@@ -7645,9 +7645,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
                hasPrimaryClip());
    }

    private boolean isWordCharacter(int position) {
        final char c = mTransformed.charAt(position);
        final int type = Character.getType(c);
    private boolean isWordCharacter(int c, int type) {
        return (c == '\'' || c == '"' ||
                type == Character.UPPERCASE_LETTER ||
                type == Character.LOWERCASE_LETTER ||
@@ -7696,35 +7694,32 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
        int start = end;

        for (; start > 0; start--) {
            if (start == end) {
                // Cases where the text ends with a '.' and we select from the end of the line
                // (right after the dot), or when we select from the space character in "aaa, bbb".
            final char c = mTransformed.charAt(start - 1);
            final int type = Character.getType(c);
                if (type == Character.OTHER_PUNCTUATION) continue;
            if (start == end && type == Character.OTHER_PUNCTUATION) { 
                // Cases where the text ends with a '.' and we select from the end of the line
                // (right after the dot), or when we select from the space character in "aaa, bbb".
                continue;
            }              
            if (!isWordCharacter(start - 1)) break;
            if (type == Character.SURROGATE) { // Two Character codepoint
                end = start - 1; // Recheck as a pair when scanning forward
                continue;
            }
            if (!isWordCharacter(c, type)) break;
            if ((end - start) > MAX_LENGTH) return -1;
        }

        for (; end < len; end++) {
            if (!isWordCharacter(end)) break;
            final int c = Character.codePointAt(mTransformed, end);
            final int type = Character.getType(c);
            if (!isWordCharacter(c, type)) break;
            if ((end - start) > MAX_LENGTH) return -1;
        }

        if (start == end) {
            return -1;
        }

        boolean hasLetter = false;
        for (int i = start; i < end; i++) {
            if (Character.isLetter(mTransformed.charAt(i))) {
                hasLetter = true;
                break;
            if (c > 0xFFFF) { // Two Character codepoint
                end++;
            }
        }

        if (!hasLetter) {
        if (start == end) {
            return -1;
        }

+12 −2
Original line number Diff line number Diff line
@@ -231,12 +231,22 @@ public class TextViewWordLimitsTest extends AndroidTestCase {
        final String SURROGATE_SYMBOL   = "\uD83D\uDE01\uD83D\uDE02\uD83D\uDE03"; // Three smileys

        // Letter Other is included even when coded as surrogate pairs
        verifyWordLimits(SURROGATE_LETTER, 1, -1, -1);
        verifyWordLimits(SURROGATE_LETTER, 2, -1, -1);
        verifyWordLimits(SURROGATE_LETTER, 0, 0, 6);
        verifyWordLimits(SURROGATE_LETTER, 1, 0, 6);
        verifyWordLimits(SURROGATE_LETTER, 2, 0, 6);
        verifyWordLimits(SURROGATE_LETTER, 3, 0, 6);
        verifyWordLimits(SURROGATE_LETTER, 4, 0, 6);
        verifyWordLimits(SURROGATE_LETTER, 5, 0, 6);
        verifyWordLimits(SURROGATE_LETTER, 6, 0, 6);

        // Not included classes are ignored even when coded as surrogate pairs
        verifyWordLimits(SURROGATE_SYMBOL, 0, -1, -1);
        verifyWordLimits(SURROGATE_SYMBOL, 1, -1, -1);
        verifyWordLimits(SURROGATE_SYMBOL, 2, -1, -1);
        verifyWordLimits(SURROGATE_SYMBOL, 3, -1, -1);
        verifyWordLimits(SURROGATE_SYMBOL, 4, -1, -1);
        verifyWordLimits(SURROGATE_SYMBOL, 5, -1, -1);
        verifyWordLimits(SURROGATE_SYMBOL, 6, -1, -1);
    }

    /**