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
This commit is contained in:
committed by
Johan Redestig
parent
f3ee6f87a3
commit
12122bf792
11
core/java/android/text/Layout.java
Normal file → Executable file
11
core/java/android/text/Layout.java
Normal file → Executable file
@@ -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 });
|
||||
|
||||
}
|
||||
|
||||
|
||||
28
core/java/android/text/StaticLayout.java
Normal file → Executable file
28
core/java/android/text/StaticLayout.java
Normal file → Executable file
@@ -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,
|
||||
spanned, i, next,
|
||||
widths, fm);
|
||||
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,
|
||||
|
||||
6
core/java/android/text/Styled.java
Normal file → Executable file
6
core/java/android/text/Styled.java
Normal file → Executable file
@@ -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;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user