diff --git a/lib/web_ui/lib/src/engine/text/measurement.dart b/lib/web_ui/lib/src/engine/text/measurement.dart index 4ca4f07e2a6d4..f6580d882afb8 100644 --- a/lib/web_ui/lib/src/engine/text/measurement.dart +++ b/lib/web_ui/lib/src/engine/text/measurement.dart @@ -429,6 +429,8 @@ class DomTextMeasurementService extends TextMeasurementService { text, startIndex: 0, endIndex: text.length, + endIndexWithoutNewlines: + _excludeTrailing(text, 0, text.length, _newlinePredicate), hardBreak: true, width: lineWidth, left: alignOffset, @@ -796,6 +798,8 @@ class LinesCalculator { _text.substring(_lineStart, breakingPoint) + _style.ellipsis, startIndex: _lineStart, endIndex: chunkEnd, + endIndexWithoutNewlines: + _excludeTrailing(_text, _chunkStart, chunkEnd, _newlinePredicate), hardBreak: false, width: widthOfResultingLine, left: alignOffset, @@ -861,6 +865,7 @@ class LinesCalculator { _text.substring(_lineStart, endWithoutNewlines), startIndex: _lineStart, endIndex: lineEnd, + endIndexWithoutNewlines: endWithoutNewlines, hardBreak: isHardBreak, width: lineWidth, left: alignOffset, diff --git a/lib/web_ui/lib/src/engine/text/paragraph.dart b/lib/web_ui/lib/src/engine/text/paragraph.dart index 9616cf598b88f..6649898a1e650 100644 --- a/lib/web_ui/lib/src/engine/text/paragraph.dart +++ b/lib/web_ui/lib/src/engine/text/paragraph.dart @@ -17,12 +17,14 @@ class EngineLineMetrics implements ui.LineMetrics { this.lineNumber, }) : text = null, startIndex = -1, - endIndex = -1; + endIndex = -1, + endIndexWithoutNewlines = -1; EngineLineMetrics.withText( this.text, { @required this.startIndex, @required this.endIndex, + @required this.endIndexWithoutNewlines, @required this.hardBreak, this.ascent, this.descent, @@ -33,6 +35,9 @@ class EngineLineMetrics implements ui.LineMetrics { this.baseline, @required this.lineNumber, }) : assert(text != null), + assert(startIndex != null), + assert(endIndex != null), + assert(endIndexWithoutNewlines != null), assert(hardBreak != null), assert(width != null), assert(left != null), @@ -50,6 +55,10 @@ class EngineLineMetrics implements ui.LineMetrics { /// the text and doesn't stop at the overflow cutoff. final int endIndex; + /// The index (exclusive) in the text where this line ends, ignoring newline + /// characters. + final int endIndexWithoutNewlines; + @override final bool hardBreak; @@ -416,7 +425,7 @@ class EngineParagraph implements ui.Paragraph { // [offset] is to the right of the line. if (offset.dx >= lineRight) { return ui.TextPosition( - offset: lineMetrics.endIndex, + offset: lineMetrics.endIndexWithoutNewlines, affinity: ui.TextAffinity.upstream, ); } @@ -429,7 +438,7 @@ class EngineParagraph implements ui.Paragraph { final TextMeasurementService instance = _measurementService; int low = lineMetrics.startIndex; - int high = lineMetrics.endIndex; + int high = lineMetrics.endIndexWithoutNewlines; do { final int current = (low + high) ~/ 2; final double width = instance.measureSubstringWidth(this, lineMetrics.startIndex, current); diff --git a/lib/web_ui/test/paragraph_test.dart b/lib/web_ui/test/paragraph_test.dart index a89250aaa515e..5a009706a69c7 100644 --- a/lib/web_ui/test/paragraph_test.dart +++ b/lib/web_ui/test/paragraph_test.dart @@ -191,7 +191,7 @@ void main() async { builder.addText('abcdefg\n'); builder.addText('ab'); final Paragraph paragraph = builder.build(); - paragraph.layout(const ParagraphConstraints(width: 1000)); + paragraph.layout(const ParagraphConstraints(width: 100)); // First line: "abcd\n" @@ -208,7 +208,7 @@ void main() async { // At the end of the first line. expect( paragraph.getPositionForOffset(Offset(50, 5)), - TextPosition(offset: 5, affinity: TextAffinity.upstream), + TextPosition(offset: 4, affinity: TextAffinity.upstream), ); // On the left side of "b" in the first line. expect( @@ -232,7 +232,7 @@ void main() async { // At the end of the second line. expect( paragraph.getPositionForOffset(Offset(100, 15)), - TextPosition(offset: 13, affinity: TextAffinity.upstream), + TextPosition(offset: 12, affinity: TextAffinity.upstream), ); // On the left side of "e" in the second line. expect( @@ -255,7 +255,7 @@ void main() async { ); // At the end of the last line. expect( - paragraph.getPositionForOffset(Offset(40, 25)), + paragraph.getPositionForOffset(Offset(100, 25)), TextPosition(offset: 15, affinity: TextAffinity.upstream), ); // Below the last line.