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