Unverified Commit 65580026 authored by Michael Goderbauer's avatar Michael Goderbauer Committed by GitHub

Add TextOverflow.visible (#28182)

parent 4ed096bd
......@@ -25,6 +25,9 @@ enum TextOverflow {
/// Use an ellipsis to indicate that the text has overflowed.
ellipsis,
/// Render overflowing text outside of its container.
visible,
}
const String _kEllipsis = '\u2026';
......@@ -268,7 +271,7 @@ class RenderParagraph extends RenderBox {
span?.recognizer?.addPointer(event);
}
bool _hasVisualOverflow = false;
bool _needsClipping = false;
ui.Shader _overflowShader;
/// Whether this paragraph currently has a [dart:ui.Shader] for its overflow
......@@ -297,15 +300,21 @@ class RenderParagraph extends RenderBox {
// visual overflow when there actually is visual overflow. This can become
// a problem if we start having horizontal overflow and introduce a clip
// that affects the actual (but undetected) vertical overflow.
_hasVisualOverflow = didOverflowWidth || didOverflowHeight;
if (_hasVisualOverflow) {
final bool hasVisualOverflow = didOverflowWidth || didOverflowHeight;
if (hasVisualOverflow) {
switch (_overflow) {
case TextOverflow.visible:
_needsClipping = false;
_overflowShader = null;
break;
case TextOverflow.clip:
case TextOverflow.ellipsis:
_needsClipping = true;
_overflowShader = null;
break;
case TextOverflow.fade:
assert(textDirection != null);
_needsClipping = true;
final TextPainter fadeSizePainter = TextPainter(
text: TextSpan(style: _textPainter.text.style, text: '\u2026'),
textDirection: textDirection,
......@@ -341,6 +350,7 @@ class RenderParagraph extends RenderBox {
break;
}
} else {
_needsClipping = false;
_overflowShader = null;
}
}
......@@ -369,7 +379,7 @@ class RenderParagraph extends RenderBox {
return true;
}());
if (_hasVisualOverflow) {
if (_needsClipping) {
final Rect bounds = offset & size;
if (_overflowShader != null) {
// This layer limits what the shader below blends with to be just the text
......@@ -381,7 +391,7 @@ class RenderParagraph extends RenderBox {
canvas.clipRect(bounds);
}
_textPainter.paint(canvas, offset);
if (_hasVisualOverflow) {
if (_needsClipping) {
if (_overflowShader != null) {
canvas.translate(offset.dx, offset.dy);
final Paint paint = Paint()
......
......@@ -21,10 +21,13 @@ import 'icon_theme_data.dart';
/// Typically this is introduced automatically by the [WidgetsApp] or
/// [MaterialApp].
///
/// This widget assumes that the rendered icon is squared. Non-squared icons may
/// render incorrectly.
///
/// {@tool sample}
///
/// This example shows how to use [Icon] to create an addition icon, in the
/// color pink, and 30 pixels in size.
/// color pink, and 30 x 30 pixels in size.
///
/// ```dart
/// Icon(
......@@ -148,6 +151,7 @@ class Icon extends StatelessWidget {
iconColor = iconColor.withOpacity(iconColor.opacity * iconOpacity);
Widget iconWidget = RichText(
overflow: TextOverflow.visible, // Never clip.
textDirection: textDirection, // Since we already fetched it for the assert...
text: TextSpan(
text: String.fromCharCode(icon.codePoint),
......
......@@ -298,6 +298,26 @@ void main() {
expect(find.byType(Text), isNot(paints..clipRect()));
});
testWidgets('Overflow is clipping correctly - long text with overflow: visible', (WidgetTester tester) async {
await _pumpTextWidget(
tester: tester,
overflow: TextOverflow.visible,
text: 'a long long long long text, should be clip',
);
expect(find.byType(Text), isNot(paints..clipRect()));
});
testWidgets('Overflow is clipping correctly - short text with overflow: visible', (WidgetTester tester) async {
await _pumpTextWidget(
tester: tester,
overflow: TextOverflow.visible,
text: 'Hi',
);
expect(find.byType(Text), isNot(paints..clipRect()));
});
}
Future<void> _pumpTextWidget({ WidgetTester tester, String text, TextOverflow overflow }) {
......
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