Skip to content

Commit 3f43d9f

Browse files
authored
Reland "Clipping if only one character text overflows (flutter#99146)" (flutter#102130)
Fixes a text clipping edge case.
1 parent e3f7560 commit 3f43d9f

File tree

3 files changed

+34
-1
lines changed

3 files changed

+34
-1
lines changed

packages/flutter/lib/src/painting/text_painter.dart

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -599,6 +599,15 @@ class TextPainter {
599599
return _paragraph!.didExceedMaxLines;
600600
}
601601

602+
/// The distance from the left edge of the leftmost glyph to the right edge of
603+
/// the rightmost glyph in the paragraph.
604+
///
605+
/// Valid only after [layout] has been called.
606+
double get longestLine {
607+
assert(!_debugNeedsLayout);
608+
return _paragraph!.longestLine;
609+
}
610+
602611
double? _lastMinWidth;
603612
double? _lastMaxWidth;
604613

packages/flutter/lib/src/rendering/paragraph.dart

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -630,6 +630,12 @@ class RenderParagraph extends RenderBox
630630
@visibleForTesting
631631
bool get debugHasOverflowShader => _overflowShader != null;
632632

633+
/// Whether this paragraph currently has overflow and needs clipping.
634+
///
635+
/// Used to test this object. Not for use in production.
636+
@visibleForTesting
637+
bool get debugNeedsClipping => _needsClipping;
638+
633639
void _layoutText({ double minWidth = 0.0, double maxWidth = double.infinity }) {
634640
final bool widthMatters = softWrap || overflow == TextOverflow.ellipsis;
635641
_textPainter.layout(
@@ -781,7 +787,7 @@ class RenderParagraph extends RenderBox
781787
size = constraints.constrain(textSize);
782788

783789
final bool didOverflowHeight = size.height < textSize.height || textDidExceedMaxLines;
784-
final bool didOverflowWidth = size.width < textSize.width;
790+
final bool didOverflowWidth = size.width < textSize.width || size.width < _textPainter.longestLine;
785791
// TODO(abarth): We're only measuring the sizes of the line boxes here. If
786792
// the glyphs draw outside the line boxes, we might think that there isn't
787793
// visual overflow when there actually is visual overflow. This can become

packages/flutter/test/rendering/paragraph_test.dart

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -326,6 +326,24 @@ void main() {
326326
expect(paragraph.debugHasOverflowShader, isFalse);
327327
}, skip: isBrowser); // https://github.com/flutter/flutter/issues/61018
328328

329+
test('one character clip test', () {
330+
// Regressing test for https://github.com/flutter/flutter/issues/99140
331+
final RenderParagraph paragraph = RenderParagraph(
332+
const TextSpan(
333+
text: '7',
334+
style: TextStyle(fontFamily: 'Ahem', fontSize: 60.0),
335+
),
336+
textDirection: TextDirection.ltr,
337+
maxLines: 1,
338+
);
339+
340+
// Lay out in a narrow box to force clipping.
341+
// The text width is 60 bigger than the constraints width.
342+
layout(paragraph, constraints: BoxConstraints.tight(const Size(50.0, 200.0)));
343+
344+
expect(paragraph.debugNeedsClipping, true);
345+
}, skip: isBrowser); // https://github.com/flutter/flutter/issues/61018
346+
329347
test('maxLines', () {
330348
final RenderParagraph paragraph = RenderParagraph(
331349
const TextSpan(

0 commit comments

Comments
 (0)