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

Commit 5bff01d7 authored by Keisuke Kuroyanagi's avatar Keisuke Kuroyanagi Committed by Raph Levien
Browse files

Respect grapheme clusters in Layout#getOffsetForHorizontal.

TextUtils#getOffsetAfter was used for getting the next
offset in Layout#getOffsetForHorizontal. However, this
method doesn't treat grapheme clusters properly.
Changed to use TextLine#getOffsetToLeftRightOf instead of
TextUtils#getOffsetAfter.

Bug: 25375561
Change-Id: I96c9e6e5da65adfb5266446ecab852c52628dbb5
parent 720edf95
Loading
Loading
Loading
Loading
+31 −24
Original line number Original line Diff line number Diff line
@@ -1131,24 +1131,30 @@ public abstract class Layout {
    public int getOffsetForHorizontal(int line, float horiz) {
    public int getOffsetForHorizontal(int line, float horiz) {
        // TODO: use Paint.getOffsetForAdvance to avoid binary search
        // TODO: use Paint.getOffsetForAdvance to avoid binary search
        final int lineEndOffset = getLineEnd(line);
        final int lineEndOffset = getLineEnd(line);
        final int lineStartOffset = getLineStart(line);

        Directions dirs = getLineDirections(line);

        TextLine tl = TextLine.obtain();
        // XXX: we don't care about tabs as we just use TextLine#getOffsetToLeftRightOf here.
        tl.set(mPaint, mText, lineStartOffset, lineEndOffset, getParagraphDirection(line), dirs,
                false, null);

        final int max;
        final int max;
        if (line == getLineCount() - 1) {
        if (line == getLineCount() - 1) {
            max = lineEndOffset;
            max = lineEndOffset;
        } else {
        } else {
            max = mPaint.getTextRunCursor(mText, 0, mText.length(),
            max = tl.getOffsetToLeftRightOf(lineEndOffset - lineStartOffset,
                    isRtlCharAt(lineEndOffset) ? Paint.DIRECTION_RTL : Paint.DIRECTION_LTR,
                    !isRtlCharAt(lineEndOffset - 1)) + lineStartOffset;
                    lineEndOffset, Paint.CURSOR_BEFORE);
        }
        }
        final int min = getLineStart(line);
        int best = lineStartOffset;
        Directions dirs = getLineDirections(line);

        int best = min;
        float bestdist = Math.abs(getPrimaryHorizontal(best) - horiz);
        float bestdist = Math.abs(getPrimaryHorizontal(best) - horiz);


        for (int i = 0; i < dirs.mDirections.length; i += 2) {
        for (int i = 0; i < dirs.mDirections.length; i += 2) {
            int here = min + dirs.mDirections[i];
            int here = lineStartOffset + dirs.mDirections[i];
            int there = here + (dirs.mDirections[i+1] & RUN_LENGTH_MASK);
            int there = here + (dirs.mDirections[i+1] & RUN_LENGTH_MASK);
            int swap = (dirs.mDirections[i+1] & RUN_RTL_FLAG) != 0 ? -1 : 1;
            boolean isRtl = (dirs.mDirections[i+1] & RUN_RTL_FLAG) != 0;
            int swap = isRtl ? -1 : 1;


            if (there > max)
            if (there > max)
                there = max;
                there = max;
@@ -1168,11 +1174,10 @@ public abstract class Layout {
                low = here + 1;
                low = here + 1;


            if (low < there) {
            if (low < there) {
                low = getOffsetAtStartOf(low);
                int aft = tl.getOffsetToLeftRightOf(low - lineStartOffset, isRtl) + lineStartOffset;

                low = tl.getOffsetToLeftRightOf(aft - lineStartOffset, !isRtl) + lineStartOffset;
                if (low >= here && low < there) {
                    float dist = Math.abs(getPrimaryHorizontal(low) - horiz);
                    float dist = Math.abs(getPrimaryHorizontal(low) - horiz);

                int aft = TextUtils.getOffsetAfter(mText, low);
                    if (aft < there) {
                    if (aft < there) {
                        float other = Math.abs(getPrimaryHorizontal(aft) - horiz);
                        float other = Math.abs(getPrimaryHorizontal(aft) - horiz);


@@ -1187,6 +1192,7 @@ public abstract class Layout {
                        best = low;
                        best = low;
                    }
                    }
                }
                }
            }


            float dist = Math.abs(getPrimaryHorizontal(here) - horiz);
            float dist = Math.abs(getPrimaryHorizontal(here) - horiz);


@@ -1203,6 +1209,7 @@ public abstract class Layout {
            best = max;
            best = max;
        }
        }


        TextLine.recycle(tl);
        return best;
        return best;
    }
    }