Unverified Commit fd41d419 authored by chunhtai's avatar chunhtai Committed by GitHub

Fix getOffsetForCaret to return correct value if contains widget span (#98542)

parent 9dc9cf57
...@@ -41,6 +41,9 @@ abstract class PlaceholderSpan extends InlineSpan { ...@@ -41,6 +41,9 @@ abstract class PlaceholderSpan extends InlineSpan {
TextStyle? style, TextStyle? style,
}) : super(style: style); }) : super(style: style);
/// The unicode character to represent a placeholder.
static const String placeholderCodeUnit = '\uFFFC';
/// How the placeholder aligns vertically with the text. /// How the placeholder aligns vertically with the text.
/// ///
/// See [ui.PlaceholderAlignment] for details on each mode. /// See [ui.PlaceholderAlignment] for details on each mode.
...@@ -57,7 +60,7 @@ abstract class PlaceholderSpan extends InlineSpan { ...@@ -57,7 +60,7 @@ abstract class PlaceholderSpan extends InlineSpan {
@override @override
void computeToPlainText(StringBuffer buffer, {bool includeSemanticsLabels = true, bool includePlaceholders = true}) { void computeToPlainText(StringBuffer buffer, {bool includeSemanticsLabels = true, bool includePlaceholders = true}) {
if (includePlaceholders) { if (includePlaceholders) {
buffer.write('\uFFFC'); buffer.write(placeholderCodeUnit);
} }
} }
......
...@@ -739,7 +739,7 @@ class TextPainter { ...@@ -739,7 +739,7 @@ class TextPainter {
// Get the Rect of the cursor (in logical pixels) based off the near edge // Get the Rect of the cursor (in logical pixels) based off the near edge
// of the character upstream from the given string offset. // of the character upstream from the given string offset.
Rect? _getRectFromUpstream(int offset, Rect caretPrototype) { Rect? _getRectFromUpstream(int offset, Rect caretPrototype) {
final String flattenedText = _text!.toPlainText(includePlaceholders: false); final String flattenedText = _text!.toPlainText(includeSemanticsLabels: false);
final int? prevCodeUnit = _text!.codeUnitAt(max(0, offset - 1)); final int? prevCodeUnit = _text!.codeUnitAt(max(0, offset - 1));
if (prevCodeUnit == null) if (prevCodeUnit == null)
return null; return null;
...@@ -789,7 +789,7 @@ class TextPainter { ...@@ -789,7 +789,7 @@ class TextPainter {
// Get the Rect of the cursor (in logical pixels) based off the near edge // Get the Rect of the cursor (in logical pixels) based off the near edge
// of the character downstream from the given string offset. // of the character downstream from the given string offset.
Rect? _getRectFromDownstream(int offset, Rect caretPrototype) { Rect? _getRectFromDownstream(int offset, Rect caretPrototype) {
final String flattenedText = _text!.toPlainText(includePlaceholders: false); final String flattenedText = _text!.toPlainText(includeSemanticsLabels: false);
// We cap the offset at the final index of the _text. // We cap the offset at the final index of the _text.
final int? nextCodeUnit = _text!.codeUnitAt(min(offset, flattenedText.length - 1)); final int? nextCodeUnit = _text!.codeUnitAt(min(offset, flattenedText.length - 1));
if (nextCodeUnit == null) if (nextCodeUnit == null)
......
...@@ -139,7 +139,8 @@ class WidgetSpan extends PlaceholderSpan { ...@@ -139,7 +139,8 @@ class WidgetSpan extends PlaceholderSpan {
@override @override
int? codeUnitAtVisitor(int index, Accumulator offset) { int? codeUnitAtVisitor(int index, Accumulator offset) {
return null; offset.increment(1);
return PlaceholderSpan.placeholderCodeUnit.codeUnitAt(0);
} }
@override @override
......
...@@ -37,6 +37,24 @@ void main() { ...@@ -37,6 +37,24 @@ void main() {
expect(caretOffset.dx, painter.width); expect(caretOffset.dx, painter.width);
}); });
test('TextPainter caret test with WidgetSpan', () {
// Regression test for https://github.com/flutter/flutter/issues/98458.
final TextPainter painter = TextPainter()
..textDirection = TextDirection.ltr;
painter.text = const TextSpan(children: <InlineSpan>[
TextSpan(text: 'before'),
WidgetSpan(child: Text('widget')),
TextSpan(text: 'after'),
]);
painter.setPlaceholderDimensions(const <PlaceholderDimensions>[
PlaceholderDimensions(size: Size(50, 30), baselineOffset: 25, alignment: ui.PlaceholderAlignment.bottom),
]);
painter.layout();
final Offset caretOffset = painter.getOffsetForCaret(ui.TextPosition(offset: painter.text!.toPlainText().length), ui.Rect.zero);
expect(caretOffset.dx, painter.width);
}, skip: isBrowser && !isCanvasKit); // https://github.com/flutter/flutter/issues/56308
test('TextPainter null text test', () { test('TextPainter null text test', () {
final TextPainter painter = TextPainter() final TextPainter painter = TextPainter()
..textDirection = TextDirection.ltr; ..textDirection = TextDirection.ltr;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment