Fix cursor position when Unicode Zs category is entered in TextField (#152215)
Changed the cursor position to be the same as before flutter 3.22.0 when 17 character codes in the Unicode Zs category are entered into a TextField. Extend the support for https://github.com/flutter/flutter/pull/149698. As a result, https://github.com/flutter/flutter/issues/149099 is resolved. The code for the Unicode-Zs category is based on the following page. https://www.compart.com/en/unicode/category/Zs Fixes https://github.com/flutter/flutter/issues/149099
This commit is contained in:
parent
1115a0d9f2
commit
112e4087e8
@ -356,11 +356,15 @@ class _TextLayout {
|
|||||||
// Luckily they have the same bidi embedding level as the paragraph as per
|
// Luckily they have the same bidi embedding level as the paragraph as per
|
||||||
// https://unicode.org/reports/tr9/#L1, so we can anchor the caret to the
|
// https://unicode.org/reports/tr9/#L1, so we can anchor the caret to the
|
||||||
// last logical trailing space.
|
// last logical trailing space.
|
||||||
final bool hasTrailingSpaces = switch (rawString.codeUnitAt(rawString.length - 1)) {
|
// Whitespace character definitions refer to Java/ICU, not Unicode-Zs.
|
||||||
0x9 || // horizontal tab
|
// https://github.com/unicode-org/icu/blob/23d9628f88a2d0127c564ad98297061c36d3ce77/icu4c/source/common/unicode/uchar.h#L3388-L3425
|
||||||
0x3000 || // ideographic space
|
final String lastCodeUnit = rawString[rawString.length - 1];
|
||||||
0x20 => true, // space
|
final bool hasTrailingSpaces = switch (lastCodeUnit.codeUnitAt(0)) {
|
||||||
_ => false,
|
0x0009 => true, // horizontal tab
|
||||||
|
0x00A0 || // no-break space
|
||||||
|
0x2007 || // figure space
|
||||||
|
0x202F => false, // narrow no-break space
|
||||||
|
_ => RegExp(r'\p{Space_Separator}', unicode: true).hasMatch(lastCodeUnit),
|
||||||
};
|
};
|
||||||
|
|
||||||
final double baseline = lineMetrics.baseline;
|
final double baseline = lineMetrics.baseline;
|
||||||
|
@ -145,20 +145,77 @@ void main() {
|
|||||||
caretOffset = painter.getOffsetForCaret(ui.TextPosition(offset: text.length), ui.Rect.zero);
|
caretOffset = painter.getOffsetForCaret(ui.TextPosition(offset: text.length), ui.Rect.zero);
|
||||||
expect(caretOffset.dx, painter.width);
|
expect(caretOffset.dx, painter.width);
|
||||||
|
|
||||||
// Test with trailing full-width space
|
/// Verify the handling of spaces by SkParagraph and TextPainter.
|
||||||
const String textWithFullWidthSpace = 'A\u{3000}';
|
///
|
||||||
checkCaretOffsetsLtr(textWithFullWidthSpace);
|
/// Test characters that are in the Unicode-Zs category but are not treated as whitespace characters by SkParagraph.
|
||||||
painter.text = const TextSpan(text: textWithFullWidthSpace);
|
/// The following character codes are intentionally excluded from the test target.
|
||||||
painter.layout();
|
/// * '\u{00A0}' (no-break space)
|
||||||
caretOffset = painter.getOffsetForCaret(const ui.TextPosition(offset: 0), ui.Rect.zero);
|
/// * '\u{2007}' (figure space)
|
||||||
expect(caretOffset.dx, 0);
|
/// * '\u{202F}' (narrow no-break space)
|
||||||
caretOffset = painter.getOffsetForCaret(const ui.TextPosition(offset: 1), ui.Rect.zero);
|
void verifyCharacterIsConsideredTrailingSpace(String character) {
|
||||||
expect(caretOffset.dx, painter.width / 2);
|
final String reason = 'character: ${character.codeUnitAt(0).toRadixString(16)}';
|
||||||
caretOffset = painter.getOffsetForCaret(const ui.TextPosition(offset: textWithFullWidthSpace.length), ui.Rect.zero);
|
|
||||||
expect(caretOffset.dx, painter.width);
|
text = 'A$character';
|
||||||
|
checkCaretOffsetsLtr(text);
|
||||||
|
painter.text = TextSpan(text: text);
|
||||||
|
painter.layout();
|
||||||
|
caretOffset = painter.getOffsetForCaret(const ui.TextPosition(offset: 0), ui.Rect.zero);
|
||||||
|
expect(caretOffset.dx, 0.0, reason: reason);
|
||||||
|
caretOffset = painter.getOffsetForCaret(const ui.TextPosition(offset: 1), ui.Rect.zero);
|
||||||
|
expect(caretOffset.dx, 14.0, reason: reason);
|
||||||
|
caretOffset = painter.getOffsetForCaret(ui.TextPosition(offset: text.length), ui.Rect.zero);
|
||||||
|
expect(caretOffset.dx, painter.width, reason: reason);
|
||||||
|
|
||||||
|
painter.layout(maxWidth: 14.0);
|
||||||
|
final List<ui.LineMetrics> lines = painter.computeLineMetrics();
|
||||||
|
expect(lines.length, 1, reason: reason);
|
||||||
|
expect(lines.first.width, 14.0, reason: reason);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test with trailing space.
|
||||||
|
verifyCharacterIsConsideredTrailingSpace('\u{0020}');
|
||||||
|
|
||||||
|
// Test with trailing full-width space.
|
||||||
|
verifyCharacterIsConsideredTrailingSpace('\u{3000}');
|
||||||
|
|
||||||
|
// Test with trailing ogham space mark.
|
||||||
|
verifyCharacterIsConsideredTrailingSpace('\u{1680}');
|
||||||
|
|
||||||
|
// Test with trailing en quad.
|
||||||
|
verifyCharacterIsConsideredTrailingSpace('\u{2000}');
|
||||||
|
|
||||||
|
// Test with trailing em quad.
|
||||||
|
verifyCharacterIsConsideredTrailingSpace('\u{2001}');
|
||||||
|
|
||||||
|
// Test with trailing en space.
|
||||||
|
verifyCharacterIsConsideredTrailingSpace('\u{2002}');
|
||||||
|
|
||||||
|
// Test with trailing em space.
|
||||||
|
verifyCharacterIsConsideredTrailingSpace('\u{2003}');
|
||||||
|
|
||||||
|
// Test with trailing three-per-em space.
|
||||||
|
verifyCharacterIsConsideredTrailingSpace('\u{2004}');
|
||||||
|
|
||||||
|
// Test with trailing four-per-em space.
|
||||||
|
verifyCharacterIsConsideredTrailingSpace('\u{2005}');
|
||||||
|
|
||||||
|
// Test with trailing six-per-em space.
|
||||||
|
verifyCharacterIsConsideredTrailingSpace('\u{2006}');
|
||||||
|
|
||||||
|
// Test with trailing punctuation space.
|
||||||
|
verifyCharacterIsConsideredTrailingSpace('\u{2008}');
|
||||||
|
|
||||||
|
// Test with trailing thin space.
|
||||||
|
verifyCharacterIsConsideredTrailingSpace('\u{2009}');
|
||||||
|
|
||||||
|
// Test with trailing hair space.
|
||||||
|
verifyCharacterIsConsideredTrailingSpace('\u{200A}');
|
||||||
|
|
||||||
|
// Test with trailing medium mathematical space(MMSP).
|
||||||
|
verifyCharacterIsConsideredTrailingSpace('\u{205F}');
|
||||||
|
|
||||||
painter.dispose();
|
painter.dispose();
|
||||||
});
|
}, skip: isBrowser && !isSkiaWeb); // https://github.com/flutter/flutter/issues/56308
|
||||||
|
|
||||||
test('TextPainter caret test with WidgetSpan', () {
|
test('TextPainter caret test with WidgetSpan', () {
|
||||||
// Regression test for https://github.com/flutter/flutter/issues/98458.
|
// Regression test for https://github.com/flutter/flutter/issues/98458.
|
||||||
|
Loading…
x
Reference in New Issue
Block a user