Skip to content

Commit 99a265b

Browse files
authored
[web] Fix edge cases in Paragraph.getPositionForOffset to match Flutter (flutter#16557)
1 parent cd11d7a commit 99a265b

File tree

3 files changed

+21
-7
lines changed

3 files changed

+21
-7
lines changed

lib/web_ui/lib/src/engine/text/measurement.dart

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -429,6 +429,8 @@ class DomTextMeasurementService extends TextMeasurementService {
429429
text,
430430
startIndex: 0,
431431
endIndex: text.length,
432+
endIndexWithoutNewlines:
433+
_excludeTrailing(text, 0, text.length, _newlinePredicate),
432434
hardBreak: true,
433435
width: lineWidth,
434436
left: alignOffset,
@@ -796,6 +798,8 @@ class LinesCalculator {
796798
_text.substring(_lineStart, breakingPoint) + _style.ellipsis,
797799
startIndex: _lineStart,
798800
endIndex: chunkEnd,
801+
endIndexWithoutNewlines:
802+
_excludeTrailing(_text, _chunkStart, chunkEnd, _newlinePredicate),
799803
hardBreak: false,
800804
width: widthOfResultingLine,
801805
left: alignOffset,
@@ -861,6 +865,7 @@ class LinesCalculator {
861865
_text.substring(_lineStart, endWithoutNewlines),
862866
startIndex: _lineStart,
863867
endIndex: lineEnd,
868+
endIndexWithoutNewlines: endWithoutNewlines,
864869
hardBreak: isHardBreak,
865870
width: lineWidth,
866871
left: alignOffset,

lib/web_ui/lib/src/engine/text/paragraph.dart

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,14 @@ class EngineLineMetrics implements ui.LineMetrics {
1717
this.lineNumber,
1818
}) : text = null,
1919
startIndex = -1,
20-
endIndex = -1;
20+
endIndex = -1,
21+
endIndexWithoutNewlines = -1;
2122

2223
EngineLineMetrics.withText(
2324
this.text, {
2425
@required this.startIndex,
2526
@required this.endIndex,
27+
@required this.endIndexWithoutNewlines,
2628
@required this.hardBreak,
2729
this.ascent,
2830
this.descent,
@@ -33,6 +35,9 @@ class EngineLineMetrics implements ui.LineMetrics {
3335
this.baseline,
3436
@required this.lineNumber,
3537
}) : assert(text != null),
38+
assert(startIndex != null),
39+
assert(endIndex != null),
40+
assert(endIndexWithoutNewlines != null),
3641
assert(hardBreak != null),
3742
assert(width != null),
3843
assert(left != null),
@@ -50,6 +55,10 @@ class EngineLineMetrics implements ui.LineMetrics {
5055
/// the text and doesn't stop at the overflow cutoff.
5156
final int endIndex;
5257

58+
/// The index (exclusive) in the text where this line ends, ignoring newline
59+
/// characters.
60+
final int endIndexWithoutNewlines;
61+
5362
@override
5463
final bool hardBreak;
5564

@@ -416,7 +425,7 @@ class EngineParagraph implements ui.Paragraph {
416425
// [offset] is to the right of the line.
417426
if (offset.dx >= lineRight) {
418427
return ui.TextPosition(
419-
offset: lineMetrics.endIndex,
428+
offset: lineMetrics.endIndexWithoutNewlines,
420429
affinity: ui.TextAffinity.upstream,
421430
);
422431
}
@@ -429,7 +438,7 @@ class EngineParagraph implements ui.Paragraph {
429438
final TextMeasurementService instance = _measurementService;
430439

431440
int low = lineMetrics.startIndex;
432-
int high = lineMetrics.endIndex;
441+
int high = lineMetrics.endIndexWithoutNewlines;
433442
do {
434443
final int current = (low + high) ~/ 2;
435444
final double width = instance.measureSubstringWidth(this, lineMetrics.startIndex, current);

lib/web_ui/test/paragraph_test.dart

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -199,7 +199,7 @@ void main() async {
199199
builder.addText('abcdefg\n');
200200
builder.addText('ab');
201201
final Paragraph paragraph = builder.build();
202-
paragraph.layout(const ParagraphConstraints(width: 1000));
202+
paragraph.layout(const ParagraphConstraints(width: 100));
203203

204204
// First line: "abcd\n"
205205

@@ -216,7 +216,7 @@ void main() async {
216216
// At the end of the first line.
217217
expect(
218218
paragraph.getPositionForOffset(Offset(50, 5)),
219-
TextPosition(offset: 5, affinity: TextAffinity.upstream),
219+
TextPosition(offset: 4, affinity: TextAffinity.upstream),
220220
);
221221
// On the left side of "b" in the first line.
222222
expect(
@@ -239,7 +239,7 @@ void main() async {
239239
// At the end of the second line.
240240
expect(
241241
paragraph.getPositionForOffset(Offset(100, 15)),
242-
TextPosition(offset: 13, affinity: TextAffinity.upstream),
242+
TextPosition(offset: 12, affinity: TextAffinity.upstream),
243243
);
244244
// On the left side of "e" in the second line.
245245
expect(
@@ -261,7 +261,7 @@ void main() async {
261261
);
262262
// At the end of the last line.
263263
expect(
264-
paragraph.getPositionForOffset(Offset(40, 25)),
264+
paragraph.getPositionForOffset(Offset(100, 25)),
265265
TextPosition(offset: 15, affinity: TextAffinity.upstream),
266266
);
267267
// Below the last line.

0 commit comments

Comments
 (0)