David PHAM-VAN

Improve TextOverflow support

... ... @@ -59,12 +59,14 @@ class Calendar extends StatelessWidget {
) {
return Container(
color: PdfColors.blue200,
padding: const EdgeInsets.all(8.0),
padding: const EdgeInsets.only(top: 8, left: 8, bottom: 8),
child: Text(
DateFormat.EEEE().format(date),
style: const TextStyle(
fontSize: 15,
),
maxLines: 1,
overflow: TextOverflow.clip,
),
);
}
... ...
... ... @@ -101,6 +101,7 @@ Future<Uint8List> generateCertificate(
),
pw.Text(
data.name,
textAlign: pw.TextAlign.center,
style: pw.TextStyle(
fontWeight: pw.FontWeight.bold,
fontSize: 20,
... ...
... ... @@ -16,6 +16,7 @@
import 'dart:typed_data';
import 'package:flutter/services.dart';
import 'package:pdf/pdf.dart';
import 'package:pdf/widgets.dart' as pw;
... ... @@ -25,7 +26,14 @@ Future<Uint8List> generateDocument(
PdfPageFormat format, CustomData data) async {
final doc = pw.Document(pageMode: PdfPageMode.outlines);
final font1 = await rootBundle.load('assets/open-sans.ttf');
final font2 = await rootBundle.load('assets/open-sans-bold.ttf');
doc.addPage(pw.MultiPage(
theme: pw.ThemeData.withFont(
base: pw.Font.ttf(font1),
bold: pw.Font.ttf(font2),
),
pageFormat: format.copyWith(marginBottom: 1.5 * PdfPageFormat.cm),
orientation: pw.PageOrientation.portrait,
crossAxisAlignment: pw.CrossAxisAlignment.start,
... ...
... ... @@ -222,6 +222,7 @@ class Invoice {
child: pw.BarcodeWidget(
barcode: pw.Barcode.pdf417(),
data: 'Invoice# $invoiceNumber',
drawText: false,
),
),
pw.Text(
... ...
... ... @@ -55,12 +55,6 @@ Future<Uint8List> generateReport(
bold: pw.Font.ttf(await rootBundle.load('assets/open-sans-bold.ttf')),
);
// Add page to the PDF
document.addPage(
pw.Page(
pageFormat: pageFormat,
theme: theme,
build: (context) {
// Top bar chart
final chart1 = pw.Chart(
left: pw.Container(
... ... @@ -129,6 +123,7 @@ Future<Uint8List> generateReport(
// Left curved line chart
final chart2 = pw.Chart(
right: pw.ChartLegend(),
grid: pw.CartesianGrid(
xAxis: pw.FixedAxis([0, 1, 2, 3, 4, 5, 6]),
yAxis: pw.FixedAxis(
... ... @@ -138,6 +133,7 @@ Future<Uint8List> generateReport(
),
datasets: [
pw.LineDataSet(
legend: 'Expense',
drawSurface: true,
isCurved: true,
drawPoints: false,
... ... @@ -185,6 +181,12 @@ Future<Uint8List> generateReport(
cellAlignments: {0: pw.Alignment.centerLeft},
);
// Add page to the PDF
document.addPage(
pw.Page(
pageFormat: pageFormat,
theme: theme,
build: (context) {
// Page layout
return pw.Column(
children: [
... ... @@ -196,17 +198,7 @@ Future<Uint8List> generateReport(
pw.Divider(thickness: 4),
pw.Expanded(flex: 3, child: chart1),
pw.Divider(),
pw.Expanded(
flex: 2,
child: pw.Row(
crossAxisAlignment: pw.CrossAxisAlignment.start,
children: [
pw.Expanded(child: chart2),
pw.SizedBox(width: 10),
pw.Expanded(child: table),
],
),
),
pw.Expanded(flex: 2, child: chart2),
pw.SizedBox(height: 10),
pw.Row(
crossAxisAlignment: pw.CrossAxisAlignment.start,
... ... @@ -275,8 +267,9 @@ Future<Uint8List> generateReport(
PdfColors.lime300,
];
return pw.SizedBox(
height: 400,
return pw.Column(
children: [
pw.Flexible(
child: pw.Chart(
title: pw.Text(
'Expense breakdown',
... ... @@ -303,6 +296,9 @@ Future<Uint8List> generateReport(
);
}),
),
),
table,
],
);
},
),
... ...
... ... @@ -141,6 +141,7 @@ Future<Uint8List> generateResume(PdfPageFormat format, CustomData data) async {
width: 60,
height: 60,
barcode: pw.Barcode.qrCode(),
drawText: false,
),
],
),
... ...
... ... @@ -11,6 +11,7 @@
- Fix textScalingFactor with lineSpacing
- Implement SpanningWidget on RichText
- Passthrough SpanningWidget on SingleChildWidget and StatelessWidget
- Improve TextOverflow support
## 3.2.0
... ...
... ... @@ -33,11 +33,14 @@ enum TextDirection { ltr, rtl }
/// How overflowing text should be handled.
enum TextOverflow {
/// Span to the next page when possible.
span,
/// Clip the overflowing text to fix its container.
clip,
/// Render overflowing text outside of its container.
visible,
/// Span to the next page when possible.
span,
}
abstract class _Span {
... ... @@ -611,7 +614,9 @@ class RichText extends Widget with SpanningWidget {
final _context = _RichTextContext();
final TextOverflow overflow;
final TextOverflow? overflow;
var _mustClip = false;
void _appendDecoration(bool append, _TextDecoration td) {
if (append && _decorations.isNotEmpty) {
... ... @@ -638,6 +643,7 @@ class RichText extends Widget with SpanningWidget {
final _maxLines = maxLines ?? theme.maxLines;
_textAlign = textAlign ?? theme.textAlign;
final _textDirection = textDirection ?? Directionality.of(context);
final _overflow = this.overflow ?? theme.overflow;
final constraintWidth = constraints.hasBoundedWidth
? constraints.maxWidth
... ... @@ -728,6 +734,7 @@ class RichText extends Widget with SpanningWidget {
// One word Overflow, try to split it.
final pos = _splitWord(word, font, style, constraintWidth);
if (pos < word.length) {
words[index] = word.substring(0, pos);
words.insert(index + 1, word.substring(pos));
... ... @@ -736,6 +743,7 @@ class RichText extends Widget with SpanningWidget {
continue;
}
}
}
final baseline = span.baseline! * textScaleFactor;
final mt = tightBounds ? metrics.top : metrics.descent;
... ... @@ -910,7 +918,10 @@ class RichText extends Widget with SpanningWidget {
..endOffset = offsetY - _context.startOffset
..spanEnd = _spans.length;
if (this.overflow != TextOverflow.span) {
if (_overflow != TextOverflow.span) {
if (_overflow != TextOverflow.visible) {
_mustClip = true;
}
return;
}
... ... @@ -949,6 +960,13 @@ class RichText extends Widget with SpanningWidget {
TextStyle? currentStyle;
PdfColor? currentColor;
if (_mustClip) {
context.canvas
..saveContext()
..drawBox(box!)
..clipPath();
}
for (var decoration in _decorations) {
assert(() {
if (Document.debug && RichText.debug) {
... ... @@ -997,6 +1015,10 @@ class RichText extends Widget with SpanningWidget {
_spans,
);
}
if (_mustClip) {
context.canvas.restoreContext();
}
}
int _splitWord(String word, PdfFont font, TextStyle style, double maxWidth) {
... ... @@ -1019,7 +1041,7 @@ class RichText extends Widget with SpanningWidget {
pos = (low + high) ~/ 2;
}
return pos;
return math.max(1, pos);
}
@override
... ... @@ -1050,7 +1072,7 @@ class Text extends RichText {
bool tightBounds = false,
double textScaleFactor = 1.0,
int? maxLines,
TextOverflow overflow = TextOverflow.visible,
TextOverflow? overflow,
}) : super(
text: TextSpan(text: text, style: style),
textAlign: textAlign,
... ...
... ... @@ -39,6 +39,7 @@ class ThemeData extends Inherited {
TextStyle? tableCell,
bool? softWrap,
TextAlign? textAlign,
TextOverflow? overflow,
int? maxLines,
IconThemeData? iconTheme,
}) {
... ... @@ -56,6 +57,7 @@ class ThemeData extends Inherited {
tableHeader: tableHeader,
tableCell: tableCell,
softWrap: softWrap,
overflow: overflow,
textAlign: textAlign,
maxLines: maxLines,
iconTheme: iconTheme,
... ... @@ -75,6 +77,7 @@ class ThemeData extends Inherited {
required this.tableHeader,
required this.tableCell,
required this.softWrap,
required this.overflow,
required this.textAlign,
required this.iconTheme,
this.maxLines,
... ... @@ -121,6 +124,7 @@ class ThemeData extends Inherited {
fontSize: fontSize * 0.8, fontWeight: FontWeight.bold),
tableCell: defaultStyle.copyWith(fontSize: fontSize * 0.8),
softWrap: true,
overflow: TextOverflow.visible,
textAlign: TextAlign.left,
iconTheme: IconThemeData.fallback(icons),
);
... ... @@ -143,6 +147,7 @@ class ThemeData extends Inherited {
bool? softWrap,
TextAlign? textAlign,
int? maxLines,
TextOverflow? overflow,
IconThemeData? iconTheme,
}) =>
ThemeData._(
... ... @@ -158,6 +163,7 @@ class ThemeData extends Inherited {
tableHeader: this.tableHeader.merge(tableHeader),
tableCell: this.tableCell.merge(tableCell),
softWrap: softWrap ?? this.softWrap,
overflow: overflow ?? this.overflow,
textAlign: textAlign ?? this.textAlign,
maxLines: maxLines ?? this.maxLines,
iconTheme: iconTheme ?? this.iconTheme,
... ... @@ -183,6 +189,7 @@ class ThemeData extends Inherited {
final TextAlign textAlign;
final bool softWrap;
final int? maxLines;
final TextOverflow overflow;
final IconThemeData iconTheme;
}
... ... @@ -216,6 +223,7 @@ class DefaultTextStyle extends StatelessWidget implements Inherited {
required this.child,
this.textAlign,
this.softWrap = true,
this.overflow,
this.maxLines,
}) : assert(maxLines == null || maxLines > 0);
... ... @@ -224,6 +232,7 @@ class DefaultTextStyle extends StatelessWidget implements Inherited {
TextAlign? textAlign,
bool? softWrap,
int? maxLines,
TextOverflow? overflow,
required Widget child,
}) {
return Builder(
... ... @@ -234,6 +243,7 @@ class DefaultTextStyle extends StatelessWidget implements Inherited {
style: parent.defaultTextStyle.merge(style),
textAlign: textAlign ?? parent.textAlign,
softWrap: softWrap ?? parent.softWrap,
overflow: overflow ?? parent.overflow,
maxLines: maxLines ?? parent.maxLines,
child: child,
);
... ... @@ -251,12 +261,15 @@ class DefaultTextStyle extends StatelessWidget implements Inherited {
final int? maxLines;
final TextOverflow? overflow;
@override
Widget build(Context context) {
final theme = Theme.of(context).copyWith(
defaultTextStyle: style,
textAlign: textAlign,
softWrap: softWrap,
overflow: overflow,
maxLines: maxLines,
);
... ...