David PHAM-VAN

Improve TextOverflow support

@@ -59,12 +59,14 @@ class Calendar extends StatelessWidget { @@ -59,12 +59,14 @@ class Calendar extends StatelessWidget {
59 ) { 59 ) {
60 return Container( 60 return Container(
61 color: PdfColors.blue200, 61 color: PdfColors.blue200,
62 - padding: const EdgeInsets.all(8.0), 62 + padding: const EdgeInsets.only(top: 8, left: 8, bottom: 8),
63 child: Text( 63 child: Text(
64 DateFormat.EEEE().format(date), 64 DateFormat.EEEE().format(date),
65 style: const TextStyle( 65 style: const TextStyle(
66 fontSize: 15, 66 fontSize: 15,
67 ), 67 ),
  68 + maxLines: 1,
  69 + overflow: TextOverflow.clip,
68 ), 70 ),
69 ); 71 );
70 } 72 }
@@ -101,6 +101,7 @@ Future<Uint8List> generateCertificate( @@ -101,6 +101,7 @@ Future<Uint8List> generateCertificate(
101 ), 101 ),
102 pw.Text( 102 pw.Text(
103 data.name, 103 data.name,
  104 + textAlign: pw.TextAlign.center,
104 style: pw.TextStyle( 105 style: pw.TextStyle(
105 fontWeight: pw.FontWeight.bold, 106 fontWeight: pw.FontWeight.bold,
106 fontSize: 20, 107 fontSize: 20,
@@ -16,6 +16,7 @@ @@ -16,6 +16,7 @@
16 16
17 import 'dart:typed_data'; 17 import 'dart:typed_data';
18 18
  19 +import 'package:flutter/services.dart';
19 import 'package:pdf/pdf.dart'; 20 import 'package:pdf/pdf.dart';
20 import 'package:pdf/widgets.dart' as pw; 21 import 'package:pdf/widgets.dart' as pw;
21 22
@@ -25,7 +26,14 @@ Future<Uint8List> generateDocument( @@ -25,7 +26,14 @@ Future<Uint8List> generateDocument(
25 PdfPageFormat format, CustomData data) async { 26 PdfPageFormat format, CustomData data) async {
26 final doc = pw.Document(pageMode: PdfPageMode.outlines); 27 final doc = pw.Document(pageMode: PdfPageMode.outlines);
27 28
  29 + final font1 = await rootBundle.load('assets/open-sans.ttf');
  30 + final font2 = await rootBundle.load('assets/open-sans-bold.ttf');
  31 +
28 doc.addPage(pw.MultiPage( 32 doc.addPage(pw.MultiPage(
  33 + theme: pw.ThemeData.withFont(
  34 + base: pw.Font.ttf(font1),
  35 + bold: pw.Font.ttf(font2),
  36 + ),
29 pageFormat: format.copyWith(marginBottom: 1.5 * PdfPageFormat.cm), 37 pageFormat: format.copyWith(marginBottom: 1.5 * PdfPageFormat.cm),
30 orientation: pw.PageOrientation.portrait, 38 orientation: pw.PageOrientation.portrait,
31 crossAxisAlignment: pw.CrossAxisAlignment.start, 39 crossAxisAlignment: pw.CrossAxisAlignment.start,
@@ -222,6 +222,7 @@ class Invoice { @@ -222,6 +222,7 @@ class Invoice {
222 child: pw.BarcodeWidget( 222 child: pw.BarcodeWidget(
223 barcode: pw.Barcode.pdf417(), 223 barcode: pw.Barcode.pdf417(),
224 data: 'Invoice# $invoiceNumber', 224 data: 'Invoice# $invoiceNumber',
  225 + drawText: false,
225 ), 226 ),
226 ), 227 ),
227 pw.Text( 228 pw.Text(
@@ -55,136 +55,138 @@ Future<Uint8List> generateReport( @@ -55,136 +55,138 @@ Future<Uint8List> generateReport(
55 bold: pw.Font.ttf(await rootBundle.load('assets/open-sans-bold.ttf')), 55 bold: pw.Font.ttf(await rootBundle.load('assets/open-sans-bold.ttf')),
56 ); 56 );
57 57
  58 + // Top bar chart
  59 + final chart1 = pw.Chart(
  60 + left: pw.Container(
  61 + alignment: pw.Alignment.topCenter,
  62 + margin: const pw.EdgeInsets.only(right: 5, top: 10),
  63 + child: pw.Transform.rotateBox(
  64 + angle: pi / 2,
  65 + child: pw.Text('Amount'),
  66 + ),
  67 + ),
  68 + overlay: pw.ChartLegend(
  69 + position: const pw.Alignment(-.7, 1),
  70 + decoration: pw.BoxDecoration(
  71 + color: PdfColors.white,
  72 + border: pw.Border.all(
  73 + color: PdfColors.black,
  74 + width: .5,
  75 + ),
  76 + ),
  77 + ),
  78 + grid: pw.CartesianGrid(
  79 + xAxis: pw.FixedAxis.fromStrings(
  80 + List<String>.generate(
  81 + dataTable.length, (index) => dataTable[index][0] as String),
  82 + marginStart: 30,
  83 + marginEnd: 30,
  84 + ticks: true,
  85 + ),
  86 + yAxis: pw.FixedAxis(
  87 + [0, 100, 200, 300, 400, 500, 600, 700],
  88 + format: (v) => '\$$v',
  89 + divisions: true,
  90 + ),
  91 + ),
  92 + datasets: [
  93 + pw.BarDataSet(
  94 + color: PdfColors.blue100,
  95 + legend: tableHeaders[2],
  96 + width: 15,
  97 + offset: -10,
  98 + borderColor: baseColor,
  99 + data: List<pw.LineChartValue>.generate(
  100 + dataTable.length,
  101 + (i) {
  102 + final v = dataTable[i][2] as num;
  103 + return pw.LineChartValue(i.toDouble(), v.toDouble());
  104 + },
  105 + ),
  106 + ),
  107 + pw.BarDataSet(
  108 + color: PdfColors.amber100,
  109 + legend: tableHeaders[1],
  110 + width: 15,
  111 + offset: 10,
  112 + borderColor: PdfColors.amber,
  113 + data: List<pw.LineChartValue>.generate(
  114 + dataTable.length,
  115 + (i) {
  116 + final v = dataTable[i][1] as num;
  117 + return pw.LineChartValue(i.toDouble(), v.toDouble());
  118 + },
  119 + ),
  120 + ),
  121 + ],
  122 + );
  123 +
  124 + // Left curved line chart
  125 + final chart2 = pw.Chart(
  126 + right: pw.ChartLegend(),
  127 + grid: pw.CartesianGrid(
  128 + xAxis: pw.FixedAxis([0, 1, 2, 3, 4, 5, 6]),
  129 + yAxis: pw.FixedAxis(
  130 + [0, 200, 400, 600],
  131 + divisions: true,
  132 + ),
  133 + ),
  134 + datasets: [
  135 + pw.LineDataSet(
  136 + legend: 'Expense',
  137 + drawSurface: true,
  138 + isCurved: true,
  139 + drawPoints: false,
  140 + color: baseColor,
  141 + data: List<pw.LineChartValue>.generate(
  142 + dataTable.length,
  143 + (i) {
  144 + final v = dataTable[i][2] as num;
  145 + return pw.LineChartValue(i.toDouble(), v.toDouble());
  146 + },
  147 + ),
  148 + ),
  149 + ],
  150 + );
  151 +
  152 + // Data table
  153 + final table = pw.Table.fromTextArray(
  154 + border: null,
  155 + headers: tableHeaders,
  156 + data: List<List<dynamic>>.generate(
  157 + dataTable.length,
  158 + (index) => <dynamic>[
  159 + dataTable[index][0],
  160 + dataTable[index][1],
  161 + dataTable[index][2],
  162 + (dataTable[index][1] as num) - (dataTable[index][2] as num),
  163 + ],
  164 + ),
  165 + headerStyle: pw.TextStyle(
  166 + color: PdfColors.white,
  167 + fontWeight: pw.FontWeight.bold,
  168 + ),
  169 + headerDecoration: pw.BoxDecoration(
  170 + color: baseColor,
  171 + ),
  172 + rowDecoration: pw.BoxDecoration(
  173 + border: pw.Border(
  174 + bottom: pw.BorderSide(
  175 + color: baseColor,
  176 + width: .5,
  177 + ),
  178 + ),
  179 + ),
  180 + cellAlignment: pw.Alignment.centerRight,
  181 + cellAlignments: {0: pw.Alignment.centerLeft},
  182 + );
  183 +
58 // Add page to the PDF 184 // Add page to the PDF
59 document.addPage( 185 document.addPage(
60 pw.Page( 186 pw.Page(
61 pageFormat: pageFormat, 187 pageFormat: pageFormat,
62 theme: theme, 188 theme: theme,
63 build: (context) { 189 build: (context) {
64 - // Top bar chart  
65 - final chart1 = pw.Chart(  
66 - left: pw.Container(  
67 - alignment: pw.Alignment.topCenter,  
68 - margin: const pw.EdgeInsets.only(right: 5, top: 10),  
69 - child: pw.Transform.rotateBox(  
70 - angle: pi / 2,  
71 - child: pw.Text('Amount'),  
72 - ),  
73 - ),  
74 - overlay: pw.ChartLegend(  
75 - position: const pw.Alignment(-.7, 1),  
76 - decoration: pw.BoxDecoration(  
77 - color: PdfColors.white,  
78 - border: pw.Border.all(  
79 - color: PdfColors.black,  
80 - width: .5,  
81 - ),  
82 - ),  
83 - ),  
84 - grid: pw.CartesianGrid(  
85 - xAxis: pw.FixedAxis.fromStrings(  
86 - List<String>.generate(  
87 - dataTable.length, (index) => dataTable[index][0] as String),  
88 - marginStart: 30,  
89 - marginEnd: 30,  
90 - ticks: true,  
91 - ),  
92 - yAxis: pw.FixedAxis(  
93 - [0, 100, 200, 300, 400, 500, 600, 700],  
94 - format: (v) => '\$$v',  
95 - divisions: true,  
96 - ),  
97 - ),  
98 - datasets: [  
99 - pw.BarDataSet(  
100 - color: PdfColors.blue100,  
101 - legend: tableHeaders[2],  
102 - width: 15,  
103 - offset: -10,  
104 - borderColor: baseColor,  
105 - data: List<pw.LineChartValue>.generate(  
106 - dataTable.length,  
107 - (i) {  
108 - final v = dataTable[i][2] as num;  
109 - return pw.LineChartValue(i.toDouble(), v.toDouble());  
110 - },  
111 - ),  
112 - ),  
113 - pw.BarDataSet(  
114 - color: PdfColors.amber100,  
115 - legend: tableHeaders[1],  
116 - width: 15,  
117 - offset: 10,  
118 - borderColor: PdfColors.amber,  
119 - data: List<pw.LineChartValue>.generate(  
120 - dataTable.length,  
121 - (i) {  
122 - final v = dataTable[i][1] as num;  
123 - return pw.LineChartValue(i.toDouble(), v.toDouble());  
124 - },  
125 - ),  
126 - ),  
127 - ],  
128 - );  
129 -  
130 - // Left curved line chart  
131 - final chart2 = pw.Chart(  
132 - grid: pw.CartesianGrid(  
133 - xAxis: pw.FixedAxis([0, 1, 2, 3, 4, 5, 6]),  
134 - yAxis: pw.FixedAxis(  
135 - [0, 200, 400, 600],  
136 - divisions: true,  
137 - ),  
138 - ),  
139 - datasets: [  
140 - pw.LineDataSet(  
141 - drawSurface: true,  
142 - isCurved: true,  
143 - drawPoints: false,  
144 - color: baseColor,  
145 - data: List<pw.LineChartValue>.generate(  
146 - dataTable.length,  
147 - (i) {  
148 - final v = dataTable[i][2] as num;  
149 - return pw.LineChartValue(i.toDouble(), v.toDouble());  
150 - },  
151 - ),  
152 - ),  
153 - ],  
154 - );  
155 -  
156 - // Data table  
157 - final table = pw.Table.fromTextArray(  
158 - border: null,  
159 - headers: tableHeaders,  
160 - data: List<List<dynamic>>.generate(  
161 - dataTable.length,  
162 - (index) => <dynamic>[  
163 - dataTable[index][0],  
164 - dataTable[index][1],  
165 - dataTable[index][2],  
166 - (dataTable[index][1] as num) - (dataTable[index][2] as num),  
167 - ],  
168 - ),  
169 - headerStyle: pw.TextStyle(  
170 - color: PdfColors.white,  
171 - fontWeight: pw.FontWeight.bold,  
172 - ),  
173 - headerDecoration: pw.BoxDecoration(  
174 - color: baseColor,  
175 - ),  
176 - rowDecoration: pw.BoxDecoration(  
177 - border: pw.Border(  
178 - bottom: pw.BorderSide(  
179 - color: baseColor,  
180 - width: .5,  
181 - ),  
182 - ),  
183 - ),  
184 - cellAlignment: pw.Alignment.centerRight,  
185 - cellAlignments: {0: pw.Alignment.centerLeft},  
186 - );  
187 -  
188 // Page layout 190 // Page layout
189 return pw.Column( 191 return pw.Column(
190 children: [ 192 children: [
@@ -196,17 +198,7 @@ Future<Uint8List> generateReport( @@ -196,17 +198,7 @@ Future<Uint8List> generateReport(
196 pw.Divider(thickness: 4), 198 pw.Divider(thickness: 4),
197 pw.Expanded(flex: 3, child: chart1), 199 pw.Expanded(flex: 3, child: chart1),
198 pw.Divider(), 200 pw.Divider(),
199 - pw.Expanded(  
200 - flex: 2,  
201 - child: pw.Row(  
202 - crossAxisAlignment: pw.CrossAxisAlignment.start,  
203 - children: [  
204 - pw.Expanded(child: chart2),  
205 - pw.SizedBox(width: 10),  
206 - pw.Expanded(child: table),  
207 - ],  
208 - ),  
209 - ), 201 + pw.Expanded(flex: 2, child: chart2),
210 pw.SizedBox(height: 10), 202 pw.SizedBox(height: 10),
211 pw.Row( 203 pw.Row(
212 crossAxisAlignment: pw.CrossAxisAlignment.start, 204 crossAxisAlignment: pw.CrossAxisAlignment.start,
@@ -275,34 +267,38 @@ Future<Uint8List> generateReport( @@ -275,34 +267,38 @@ Future<Uint8List> generateReport(
275 PdfColors.lime300, 267 PdfColors.lime300,
276 ]; 268 ];
277 269
278 - return pw.SizedBox(  
279 - height: 400,  
280 - child: pw.Chart(  
281 - title: pw.Text(  
282 - 'Expense breakdown',  
283 - style: pw.TextStyle(  
284 - color: baseColor,  
285 - fontSize: 20,  
286 - ),  
287 - ),  
288 - grid: pw.PieGrid(),  
289 - datasets: List<pw.Dataset>.generate(dataTable.length, (index) {  
290 - final data = dataTable[index];  
291 - final color = chartColors[index % chartColors.length];  
292 - final textColor =  
293 - color.luminance < 0.2 ? PdfColors.white : PdfColors.black; 270 + return pw.Column(
  271 + children: [
  272 + pw.Flexible(
  273 + child: pw.Chart(
  274 + title: pw.Text(
  275 + 'Expense breakdown',
  276 + style: pw.TextStyle(
  277 + color: baseColor,
  278 + fontSize: 20,
  279 + ),
  280 + ),
  281 + grid: pw.PieGrid(),
  282 + datasets: List<pw.Dataset>.generate(dataTable.length, (index) {
  283 + final data = dataTable[index];
  284 + final color = chartColors[index % chartColors.length];
  285 + final textColor =
  286 + color.luminance < 0.2 ? PdfColors.white : PdfColors.black;
294 287
295 - final value = (data[2] as num).toDouble();  
296 - final pct = (value / expense * 100).round(); 288 + final value = (data[2] as num).toDouble();
  289 + final pct = (value / expense * 100).round();
297 290
298 - return pw.PieDataSet(  
299 - legend: '${data[0]}\n$pct%',  
300 - value: value,  
301 - color: color,  
302 - legendStyle: pw.TextStyle(fontSize: 10, color: textColor),  
303 - );  
304 - }),  
305 - ), 291 + return pw.PieDataSet(
  292 + legend: '${data[0]}\n$pct%',
  293 + value: value,
  294 + color: color,
  295 + legendStyle: pw.TextStyle(fontSize: 10, color: textColor),
  296 + );
  297 + }),
  298 + ),
  299 + ),
  300 + table,
  301 + ],
306 ); 302 );
307 }, 303 },
308 ), 304 ),
@@ -141,6 +141,7 @@ Future<Uint8List> generateResume(PdfPageFormat format, CustomData data) async { @@ -141,6 +141,7 @@ Future<Uint8List> generateResume(PdfPageFormat format, CustomData data) async {
141 width: 60, 141 width: 60,
142 height: 60, 142 height: 60,
143 barcode: pw.Barcode.qrCode(), 143 barcode: pw.Barcode.qrCode(),
  144 + drawText: false,
144 ), 145 ),
145 ], 146 ],
146 ), 147 ),
@@ -11,6 +11,7 @@ @@ -11,6 +11,7 @@
11 - Fix textScalingFactor with lineSpacing 11 - Fix textScalingFactor with lineSpacing
12 - Implement SpanningWidget on RichText 12 - Implement SpanningWidget on RichText
13 - Passthrough SpanningWidget on SingleChildWidget and StatelessWidget 13 - Passthrough SpanningWidget on SingleChildWidget and StatelessWidget
  14 +- Improve TextOverflow support
14 15
15 ## 3.2.0 16 ## 3.2.0
16 17
@@ -33,11 +33,14 @@ enum TextDirection { ltr, rtl } @@ -33,11 +33,14 @@ enum TextDirection { ltr, rtl }
33 33
34 /// How overflowing text should be handled. 34 /// How overflowing text should be handled.
35 enum TextOverflow { 35 enum TextOverflow {
36 - /// Span to the next page when possible.  
37 - span, 36 + /// Clip the overflowing text to fix its container.
  37 + clip,
38 38
39 /// Render overflowing text outside of its container. 39 /// Render overflowing text outside of its container.
40 visible, 40 visible,
  41 +
  42 + /// Span to the next page when possible.
  43 + span,
41 } 44 }
42 45
43 abstract class _Span { 46 abstract class _Span {
@@ -611,7 +614,9 @@ class RichText extends Widget with SpanningWidget { @@ -611,7 +614,9 @@ class RichText extends Widget with SpanningWidget {
611 614
612 final _context = _RichTextContext(); 615 final _context = _RichTextContext();
613 616
614 - final TextOverflow overflow; 617 + final TextOverflow? overflow;
  618 +
  619 + var _mustClip = false;
615 620
616 void _appendDecoration(bool append, _TextDecoration td) { 621 void _appendDecoration(bool append, _TextDecoration td) {
617 if (append && _decorations.isNotEmpty) { 622 if (append && _decorations.isNotEmpty) {
@@ -638,6 +643,7 @@ class RichText extends Widget with SpanningWidget { @@ -638,6 +643,7 @@ class RichText extends Widget with SpanningWidget {
638 final _maxLines = maxLines ?? theme.maxLines; 643 final _maxLines = maxLines ?? theme.maxLines;
639 _textAlign = textAlign ?? theme.textAlign; 644 _textAlign = textAlign ?? theme.textAlign;
640 final _textDirection = textDirection ?? Directionality.of(context); 645 final _textDirection = textDirection ?? Directionality.of(context);
  646 + final _overflow = this.overflow ?? theme.overflow;
641 647
642 final constraintWidth = constraints.hasBoundedWidth 648 final constraintWidth = constraints.hasBoundedWidth
643 ? constraints.maxWidth 649 ? constraints.maxWidth
@@ -728,12 +734,14 @@ class RichText extends Widget with SpanningWidget { @@ -728,12 +734,14 @@ class RichText extends Widget with SpanningWidget {
728 // One word Overflow, try to split it. 734 // One word Overflow, try to split it.
729 final pos = _splitWord(word, font, style, constraintWidth); 735 final pos = _splitWord(word, font, style, constraintWidth);
730 736
731 - words[index] = word.substring(0, pos);  
732 - words.insert(index + 1, word.substring(pos)); 737 + if (pos < word.length) {
  738 + words[index] = word.substring(0, pos);
  739 + words.insert(index + 1, word.substring(pos));
733 740
734 - // Try again  
735 - index--;  
736 - continue; 741 + // Try again
  742 + index--;
  743 + continue;
  744 + }
737 } 745 }
738 } 746 }
739 747
@@ -910,7 +918,10 @@ class RichText extends Widget with SpanningWidget { @@ -910,7 +918,10 @@ class RichText extends Widget with SpanningWidget {
910 ..endOffset = offsetY - _context.startOffset 918 ..endOffset = offsetY - _context.startOffset
911 ..spanEnd = _spans.length; 919 ..spanEnd = _spans.length;
912 920
913 - if (this.overflow != TextOverflow.span) { 921 + if (_overflow != TextOverflow.span) {
  922 + if (_overflow != TextOverflow.visible) {
  923 + _mustClip = true;
  924 + }
914 return; 925 return;
915 } 926 }
916 927
@@ -949,6 +960,13 @@ class RichText extends Widget with SpanningWidget { @@ -949,6 +960,13 @@ class RichText extends Widget with SpanningWidget {
949 TextStyle? currentStyle; 960 TextStyle? currentStyle;
950 PdfColor? currentColor; 961 PdfColor? currentColor;
951 962
  963 + if (_mustClip) {
  964 + context.canvas
  965 + ..saveContext()
  966 + ..drawBox(box!)
  967 + ..clipPath();
  968 + }
  969 +
952 for (var decoration in _decorations) { 970 for (var decoration in _decorations) {
953 assert(() { 971 assert(() {
954 if (Document.debug && RichText.debug) { 972 if (Document.debug && RichText.debug) {
@@ -997,6 +1015,10 @@ class RichText extends Widget with SpanningWidget { @@ -997,6 +1015,10 @@ class RichText extends Widget with SpanningWidget {
997 _spans, 1015 _spans,
998 ); 1016 );
999 } 1017 }
  1018 +
  1019 + if (_mustClip) {
  1020 + context.canvas.restoreContext();
  1021 + }
1000 } 1022 }
1001 1023
1002 int _splitWord(String word, PdfFont font, TextStyle style, double maxWidth) { 1024 int _splitWord(String word, PdfFont font, TextStyle style, double maxWidth) {
@@ -1019,7 +1041,7 @@ class RichText extends Widget with SpanningWidget { @@ -1019,7 +1041,7 @@ class RichText extends Widget with SpanningWidget {
1019 pos = (low + high) ~/ 2; 1041 pos = (low + high) ~/ 2;
1020 } 1042 }
1021 1043
1022 - return pos; 1044 + return math.max(1, pos);
1023 } 1045 }
1024 1046
1025 @override 1047 @override
@@ -1050,7 +1072,7 @@ class Text extends RichText { @@ -1050,7 +1072,7 @@ class Text extends RichText {
1050 bool tightBounds = false, 1072 bool tightBounds = false,
1051 double textScaleFactor = 1.0, 1073 double textScaleFactor = 1.0,
1052 int? maxLines, 1074 int? maxLines,
1053 - TextOverflow overflow = TextOverflow.visible, 1075 + TextOverflow? overflow,
1054 }) : super( 1076 }) : super(
1055 text: TextSpan(text: text, style: style), 1077 text: TextSpan(text: text, style: style),
1056 textAlign: textAlign, 1078 textAlign: textAlign,
@@ -39,6 +39,7 @@ class ThemeData extends Inherited { @@ -39,6 +39,7 @@ class ThemeData extends Inherited {
39 TextStyle? tableCell, 39 TextStyle? tableCell,
40 bool? softWrap, 40 bool? softWrap,
41 TextAlign? textAlign, 41 TextAlign? textAlign,
  42 + TextOverflow? overflow,
42 int? maxLines, 43 int? maxLines,
43 IconThemeData? iconTheme, 44 IconThemeData? iconTheme,
44 }) { 45 }) {
@@ -56,6 +57,7 @@ class ThemeData extends Inherited { @@ -56,6 +57,7 @@ class ThemeData extends Inherited {
56 tableHeader: tableHeader, 57 tableHeader: tableHeader,
57 tableCell: tableCell, 58 tableCell: tableCell,
58 softWrap: softWrap, 59 softWrap: softWrap,
  60 + overflow: overflow,
59 textAlign: textAlign, 61 textAlign: textAlign,
60 maxLines: maxLines, 62 maxLines: maxLines,
61 iconTheme: iconTheme, 63 iconTheme: iconTheme,
@@ -75,6 +77,7 @@ class ThemeData extends Inherited { @@ -75,6 +77,7 @@ class ThemeData extends Inherited {
75 required this.tableHeader, 77 required this.tableHeader,
76 required this.tableCell, 78 required this.tableCell,
77 required this.softWrap, 79 required this.softWrap,
  80 + required this.overflow,
78 required this.textAlign, 81 required this.textAlign,
79 required this.iconTheme, 82 required this.iconTheme,
80 this.maxLines, 83 this.maxLines,
@@ -121,6 +124,7 @@ class ThemeData extends Inherited { @@ -121,6 +124,7 @@ class ThemeData extends Inherited {
121 fontSize: fontSize * 0.8, fontWeight: FontWeight.bold), 124 fontSize: fontSize * 0.8, fontWeight: FontWeight.bold),
122 tableCell: defaultStyle.copyWith(fontSize: fontSize * 0.8), 125 tableCell: defaultStyle.copyWith(fontSize: fontSize * 0.8),
123 softWrap: true, 126 softWrap: true,
  127 + overflow: TextOverflow.visible,
124 textAlign: TextAlign.left, 128 textAlign: TextAlign.left,
125 iconTheme: IconThemeData.fallback(icons), 129 iconTheme: IconThemeData.fallback(icons),
126 ); 130 );
@@ -143,6 +147,7 @@ class ThemeData extends Inherited { @@ -143,6 +147,7 @@ class ThemeData extends Inherited {
143 bool? softWrap, 147 bool? softWrap,
144 TextAlign? textAlign, 148 TextAlign? textAlign,
145 int? maxLines, 149 int? maxLines,
  150 + TextOverflow? overflow,
146 IconThemeData? iconTheme, 151 IconThemeData? iconTheme,
147 }) => 152 }) =>
148 ThemeData._( 153 ThemeData._(
@@ -158,6 +163,7 @@ class ThemeData extends Inherited { @@ -158,6 +163,7 @@ class ThemeData extends Inherited {
158 tableHeader: this.tableHeader.merge(tableHeader), 163 tableHeader: this.tableHeader.merge(tableHeader),
159 tableCell: this.tableCell.merge(tableCell), 164 tableCell: this.tableCell.merge(tableCell),
160 softWrap: softWrap ?? this.softWrap, 165 softWrap: softWrap ?? this.softWrap,
  166 + overflow: overflow ?? this.overflow,
161 textAlign: textAlign ?? this.textAlign, 167 textAlign: textAlign ?? this.textAlign,
162 maxLines: maxLines ?? this.maxLines, 168 maxLines: maxLines ?? this.maxLines,
163 iconTheme: iconTheme ?? this.iconTheme, 169 iconTheme: iconTheme ?? this.iconTheme,
@@ -183,6 +189,7 @@ class ThemeData extends Inherited { @@ -183,6 +189,7 @@ class ThemeData extends Inherited {
183 final TextAlign textAlign; 189 final TextAlign textAlign;
184 final bool softWrap; 190 final bool softWrap;
185 final int? maxLines; 191 final int? maxLines;
  192 + final TextOverflow overflow;
186 193
187 final IconThemeData iconTheme; 194 final IconThemeData iconTheme;
188 } 195 }
@@ -216,6 +223,7 @@ class DefaultTextStyle extends StatelessWidget implements Inherited { @@ -216,6 +223,7 @@ class DefaultTextStyle extends StatelessWidget implements Inherited {
216 required this.child, 223 required this.child,
217 this.textAlign, 224 this.textAlign,
218 this.softWrap = true, 225 this.softWrap = true,
  226 + this.overflow,
219 this.maxLines, 227 this.maxLines,
220 }) : assert(maxLines == null || maxLines > 0); 228 }) : assert(maxLines == null || maxLines > 0);
221 229
@@ -224,6 +232,7 @@ class DefaultTextStyle extends StatelessWidget implements Inherited { @@ -224,6 +232,7 @@ class DefaultTextStyle extends StatelessWidget implements Inherited {
224 TextAlign? textAlign, 232 TextAlign? textAlign,
225 bool? softWrap, 233 bool? softWrap,
226 int? maxLines, 234 int? maxLines,
  235 + TextOverflow? overflow,
227 required Widget child, 236 required Widget child,
228 }) { 237 }) {
229 return Builder( 238 return Builder(
@@ -234,6 +243,7 @@ class DefaultTextStyle extends StatelessWidget implements Inherited { @@ -234,6 +243,7 @@ class DefaultTextStyle extends StatelessWidget implements Inherited {
234 style: parent.defaultTextStyle.merge(style), 243 style: parent.defaultTextStyle.merge(style),
235 textAlign: textAlign ?? parent.textAlign, 244 textAlign: textAlign ?? parent.textAlign,
236 softWrap: softWrap ?? parent.softWrap, 245 softWrap: softWrap ?? parent.softWrap,
  246 + overflow: overflow ?? parent.overflow,
237 maxLines: maxLines ?? parent.maxLines, 247 maxLines: maxLines ?? parent.maxLines,
238 child: child, 248 child: child,
239 ); 249 );
@@ -251,12 +261,15 @@ class DefaultTextStyle extends StatelessWidget implements Inherited { @@ -251,12 +261,15 @@ class DefaultTextStyle extends StatelessWidget implements Inherited {
251 261
252 final int? maxLines; 262 final int? maxLines;
253 263
  264 + final TextOverflow? overflow;
  265 +
254 @override 266 @override
255 Widget build(Context context) { 267 Widget build(Context context) {
256 final theme = Theme.of(context).copyWith( 268 final theme = Theme.of(context).copyWith(
257 defaultTextStyle: style, 269 defaultTextStyle: style,
258 textAlign: textAlign, 270 textAlign: textAlign,
259 softWrap: softWrap, 271 softWrap: softWrap,
  272 + overflow: overflow,
260 maxLines: maxLines, 273 maxLines: maxLines,
261 ); 274 );
262 275