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

Commit 12122bf7 authored by Takako Ishibashi's avatar Takako Ishibashi Committed by Johan Redestig
Browse files

Support surrogate pairs when layouting text

The current framework does not consider surrogate pairs
when getting the index of the character. This bug becomes
visible when creating the text including Emojis. For
example cursor breaks up when it moves around the Emojis.

Our proposed solution will consider the surrogate pairs
when calculating the index. It will fix not only the Emoji
case, but also the letters that use surrogate pairs.

Change-Id: I4983f2e4df933c8af9d5f0cc27df871e8e10fed4
parent f3ee6f87
Loading
Loading
Loading
Loading
+7 −4
Original line number Diff line number Diff line
@@ -749,6 +749,9 @@ public abstract class Layout {
        if (line == getLineCount() - 1)
            max++;

        if (line != getLineCount() - 1)
            max = TextUtils.getOffsetBefore(mText, getLineEnd(line));

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

@@ -893,7 +896,7 @@ public abstract class Layout {
        Directions dirs = getLineDirections(line);

        if (line != getLineCount() - 1)
            end--;
            end = TextUtils.getOffsetBefore(mText, end);

        float horiz = getPrimaryHorizontal(offset);

@@ -993,7 +996,7 @@ public abstract class Layout {
        Directions dirs = getLineDirections(line);

        if (line != getLineCount() - 1)
            end--;
            end = TextUtils.getOffsetBefore(mText, end);

        float horiz = getPrimaryHorizontal(offset);

@@ -1564,7 +1567,8 @@ public abstract class Layout {
                        h = dir * nextTab(text, start, end, h * dir, tabs);
                    }

                    if (bm != null) {
                    if (j != there && bm != null) {
                        if (offset == start + j) return h;
                        workPaint.set(paint);
                        Styled.measureText(paint, workPaint, text,
                                           j, j + 2, null);
@@ -1958,4 +1962,3 @@ public abstract class Layout {
                                       new Directions(new short[] { 0, 32767 });

}
+24 −4
Original line number Diff line number Diff line
@@ -313,7 +313,9 @@ extends Layout
                                                      class);

                if (spanned == null) {
                    paint.getTextWidths(sub, i, next, widths);
                    final int actualNum = paint.getTextWidths(sub, i, next, widths);
                    if (next - i > actualNum)
                        adjustTextWidths(widths, sub, i, next, actualNum);
                    System.arraycopy(widths, 0, widths,
                                     end - start + (i - start), next - i);
                                     
@@ -321,9 +323,11 @@ extends Layout
                } else {
                    mWorkPaint.baselineShift = 0;

                    Styled.getTextWidths(paint, mWorkPaint,
                    final int actualNum = Styled.getTextWidths(paint, mWorkPaint,
                            spanned, i, next,
                            widths, fm);
                    if (next - i > actualNum)
                        adjustTextWidths(widths, spanned, i, next, actualNum);
                    System.arraycopy(widths, 0, widths,
                                     end - start + (i - start), next - i);

@@ -966,6 +970,22 @@ extends Layout
            return low;
    }

    private static void adjustTextWidths(float[] widths, CharSequence text,
                              int curPos, int nextPos, int actualNum) {
        try {
            int dstIndex = nextPos - curPos - 1;
            for (int srcIndex = actualNum - 1; srcIndex >= 0; srcIndex--) {
                final char c = text.charAt(dstIndex + curPos);
                if (c >= 0xD800 && c <= 0xDFFF) {
                    widths[dstIndex--] = 0.0f;
                }
                widths[dstIndex--] = widths[srcIndex];
            }
        } catch (IndexOutOfBoundsException e) {
            Log.e("text", "adjust text widths failed");
        }
    }

    private int out(CharSequence text, int start, int end,
                      int above, int below, int top, int bottom, int v,
                      float spacingmult, float spacingadd,
+4 −2
Original line number Diff line number Diff line
@@ -203,9 +203,10 @@ public class Styled
			}
		}
	
        int result;
        if (replacement == null) {
            workPaint.getFontMetricsInt(fmi);
            workPaint.getTextWidths(text, start, end, widths);
            result = workPaint.getTextWidths(text, start, end, widths);
        } else {
            int wid = replacement.getSize(workPaint, text, start, end, fmi);

@@ -214,8 +215,9 @@ public class Styled
                for (int i = start + 1; i < end; i++)
                    widths[i - start] = 0;
            }
            result = end - start;
        }
        return end - start;
        return result;
    }

    /**