Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

Commit 1370c9d

Browse files
Revert "[web] Correct getPositionForOffset for multi-line paragraphs (#16206)" (#16268)
This reverts commit 4ac82f6. This caused a regression in a framework test (material/text_field_splash_test.dart)
1 parent 4655295 commit 1370c9d

File tree

3 files changed

+8
-195
lines changed

3 files changed

+8
-195
lines changed

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

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -373,10 +373,7 @@ class DomTextMeasurementService extends TextMeasurementService {
373373
@override
374374
ui.TextPosition getTextPositionForOffset(EngineParagraph paragraph,
375375
ui.ParagraphConstraints constraints, ui.Offset offset) {
376-
assert(
377-
paragraph._measurementResult.lines == null,
378-
'should only be called when the faster lines-based approach is not possible',
379-
);
376+
assert(paragraph._plainText == null, 'should only be called for multispan');
380377

381378
final ParagraphGeometricStyle style = paragraph._geometricStyle;
382379
final ParagraphRuler ruler =

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

Lines changed: 6 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -378,53 +378,17 @@ class EngineParagraph implements ui.Paragraph {
378378

379379
@override
380380
ui.TextPosition getPositionForOffset(ui.Offset offset) {
381-
final List<EngineLineMetrics> lines = _measurementResult.lines;
382-
if (lines == null) {
381+
if (_plainText == null) {
383382
return getPositionForMultiSpanOffset(offset);
384383
}
385-
386-
final int lineNumber = offset.dy ~/ _measurementResult.lineHeight;
387-
388-
// [offset] is below all the lines.
389-
if (lineNumber >= lines.length) {
390-
return ui.TextPosition(
391-
offset: _plainText.length,
392-
affinity: ui.TextAffinity.upstream,
393-
);
394-
}
395-
396-
final EngineLineMetrics lineMetrics = lines[lineNumber];
397-
final double lineLeft = lineMetrics.left;
398-
final double lineRight = lineLeft + lineMetrics.width;
399-
400-
// [offset] is to the left of the line.
401-
if (offset.dx <= lineLeft) {
402-
return ui.TextPosition(
403-
offset: lineMetrics.startIndex,
404-
affinity: ui.TextAffinity.downstream,
405-
);
406-
}
407-
408-
// [offset] is to the right of the line.
409-
if (offset.dx >= lineRight) {
410-
return ui.TextPosition(
411-
offset: lineMetrics.endIndex,
412-
affinity: ui.TextAffinity.upstream,
413-
);
414-
}
415-
416-
// If we reach here, it means the [offset] is somewhere within the line. The
417-
// code below will do a binary search to find where exactly the [offset]
418-
// falls within the line.
419-
420384
final double dx = offset.dx - _alignOffset;
421385
final TextMeasurementService instance = _measurementService;
422386

423-
int low = lineMetrics.startIndex;
424-
int high = lineMetrics.endIndex;
387+
int low = 0;
388+
int high = _plainText.length;
425389
do {
426390
final int current = (low + high) ~/ 2;
427-
final double width = instance.measureSubstringWidth(this, lineMetrics.startIndex, current);
391+
final double width = instance.measureSubstringWidth(this, 0, current);
428392
if (width < dx) {
429393
low = current;
430394
} else if (width > dx) {
@@ -439,8 +403,8 @@ class EngineParagraph implements ui.Paragraph {
439403
return ui.TextPosition(offset: high, affinity: ui.TextAffinity.upstream);
440404
}
441405

442-
final double lowWidth = instance.measureSubstringWidth(this, lineMetrics.startIndex, low);
443-
final double highWidth = instance.measureSubstringWidth(this, lineMetrics.startIndex, high);
406+
final double lowWidth = instance.measureSubstringWidth(this, 0, low);
407+
final double highWidth = instance.measureSubstringWidth(this, 0, high);
444408

445409
if (dx - lowWidth < highWidth - dx) {
446410
// The offset is closer to the low index.

lib/web_ui/test/paragraph_test.dart

Lines changed: 1 addition & 149 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import 'package:ui/ui.dart';
88
import 'package:test/test.dart';
99

1010
void testEachMeasurement(String description, VoidCallback body, {bool skip}) {
11-
test('$description (dom measurement)', () async {
11+
test(description, () async {
1212
try {
1313
TextMeasurementService.initialize(rulerCacheCapacity: 2);
1414
return body();
@@ -130,154 +130,6 @@ void main() async {
130130
}, // TODO(nurhan): https://github.com/flutter/flutter/issues/46638
131131
skip: (browserEngine == BrowserEngine.firefox));
132132

133-
testEachMeasurement('getPositionForOffset single-line', () {
134-
final ParagraphBuilder builder = ParagraphBuilder(ParagraphStyle(
135-
fontFamily: 'Ahem',
136-
fontStyle: FontStyle.normal,
137-
fontWeight: FontWeight.normal,
138-
fontSize: 10,
139-
textDirection: TextDirection.ltr,
140-
));
141-
builder.addText('abcd efg');
142-
final Paragraph paragraph = builder.build();
143-
paragraph.layout(const ParagraphConstraints(width: 1000));
144-
145-
// At the beginning of the line.
146-
expect(
147-
paragraph.getPositionForOffset(Offset(0, 5)),
148-
TextPosition(offset: 0, affinity: TextAffinity.downstream),
149-
);
150-
// Below the line.
151-
expect(
152-
paragraph.getPositionForOffset(Offset(0, 12)),
153-
TextPosition(offset: 8, affinity: TextAffinity.upstream),
154-
);
155-
// Above the line.
156-
expect(
157-
paragraph.getPositionForOffset(Offset(0, -5)),
158-
TextPosition(offset: 0, affinity: TextAffinity.downstream),
159-
);
160-
// At the end of the line.
161-
expect(
162-
paragraph.getPositionForOffset(Offset(80, 5)),
163-
TextPosition(offset: 8, affinity: TextAffinity.upstream),
164-
);
165-
// On the left side of "b".
166-
expect(
167-
paragraph.getPositionForOffset(Offset(14, 5)),
168-
TextPosition(offset: 1, affinity: TextAffinity.downstream),
169-
);
170-
// On the right side of "b".
171-
expect(
172-
paragraph.getPositionForOffset(Offset(16, 5)),
173-
TextPosition(offset: 2, affinity: TextAffinity.upstream),
174-
);
175-
});
176-
177-
test('getPositionForOffset multi-line', () {
178-
// [Paragraph.getPositionForOffset] for multi-line text doesn't work well
179-
// with dom-based measurement.
180-
TextMeasurementService.enableExperimentalCanvasImplementation = true;
181-
TextMeasurementService.initialize(rulerCacheCapacity: 2);
182-
183-
final ParagraphBuilder builder = ParagraphBuilder(ParagraphStyle(
184-
fontFamily: 'Ahem',
185-
fontStyle: FontStyle.normal,
186-
fontWeight: FontWeight.normal,
187-
fontSize: 10,
188-
textDirection: TextDirection.ltr,
189-
));
190-
builder.addText('abcd\n');
191-
builder.addText('abcdefg\n');
192-
builder.addText('ab');
193-
final Paragraph paragraph = builder.build();
194-
paragraph.layout(const ParagraphConstraints(width: 1000));
195-
196-
// First line: "abcd\n"
197-
198-
// At the beginning of the first line.
199-
expect(
200-
paragraph.getPositionForOffset(Offset(0, 5)),
201-
TextPosition(offset: 0, affinity: TextAffinity.downstream),
202-
);
203-
// Above the first line.
204-
expect(
205-
paragraph.getPositionForOffset(Offset(0, -5)),
206-
TextPosition(offset: 0, affinity: TextAffinity.downstream),
207-
);
208-
// At the end of the first line.
209-
expect(
210-
paragraph.getPositionForOffset(Offset(50, 5)),
211-
TextPosition(offset: 5, affinity: TextAffinity.upstream),
212-
);
213-
// On the left side of "b" in the first line.
214-
expect(
215-
paragraph.getPositionForOffset(Offset(14, 5)),
216-
TextPosition(offset: 1, affinity: TextAffinity.downstream),
217-
);
218-
// On the right side of "b" in the first line.
219-
expect(
220-
paragraph.getPositionForOffset(Offset(16, 5)),
221-
TextPosition(offset: 2, affinity: TextAffinity.upstream),
222-
);
223-
224-
225-
// Second line: "abcdefg\n"
226-
227-
// At the beginning of the second line.
228-
expect(
229-
paragraph.getPositionForOffset(Offset(0, 15)),
230-
TextPosition(offset: 5, affinity: TextAffinity.downstream),
231-
);
232-
// At the end of the second line.
233-
expect(
234-
paragraph.getPositionForOffset(Offset(100, 15)),
235-
TextPosition(offset: 13, affinity: TextAffinity.upstream),
236-
);
237-
// On the left side of "e" in the second line.
238-
expect(
239-
paragraph.getPositionForOffset(Offset(44, 15)),
240-
TextPosition(offset: 9, affinity: TextAffinity.downstream),
241-
);
242-
// On the right side of "e" in the second line.
243-
expect(
244-
paragraph.getPositionForOffset(Offset(46, 15)),
245-
TextPosition(offset: 10, affinity: TextAffinity.upstream),
246-
);
247-
248-
249-
// Last (third) line: "ab"
250-
251-
// At the beginning of the last line.
252-
expect(
253-
paragraph.getPositionForOffset(Offset(0, 25)),
254-
TextPosition(offset: 13, affinity: TextAffinity.downstream),
255-
);
256-
// At the end of the last line.
257-
expect(
258-
paragraph.getPositionForOffset(Offset(40, 25)),
259-
TextPosition(offset: 15, affinity: TextAffinity.upstream),
260-
);
261-
// Below the last line.
262-
expect(
263-
paragraph.getPositionForOffset(Offset(0, 32)),
264-
TextPosition(offset: 15, affinity: TextAffinity.upstream),
265-
);
266-
// On the left side of "b" in the last line.
267-
expect(
268-
paragraph.getPositionForOffset(Offset(12, 25)),
269-
TextPosition(offset: 14, affinity: TextAffinity.downstream),
270-
);
271-
// On the right side of "a" in the last line.
272-
expect(
273-
paragraph.getPositionForOffset(Offset(9, 25)),
274-
TextPosition(offset: 14, affinity: TextAffinity.upstream),
275-
);
276-
277-
TextMeasurementService.clearCache();
278-
TextMeasurementService.enableExperimentalCanvasImplementation = false;
279-
});
280-
281133
testEachMeasurement('getBoxesForRange returns a box', () {
282134
final ParagraphBuilder builder = ParagraphBuilder(ParagraphStyle(
283135
fontFamily: 'Ahem',

0 commit comments

Comments
 (0)