Skip to content

Commit 27e9a16

Browse files
committed
Fix Mid-word line break inside table
1 parent 4146df6 commit 27e9a16

File tree

5 files changed

+74
-22
lines changed

5 files changed

+74
-22
lines changed

pdf/lib/src/pdf/rect.dart

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -20,18 +20,20 @@ import 'point.dart';
2020

2121
@immutable
2222
class PdfRect {
23-
const PdfRect(this.x, this.y, this.width, this.height);
23+
const PdfRect(this.x, this.y, this.width, this.height, [this.minWidth]);
2424

25-
factory PdfRect.fromLTRB(
26-
double left, double top, double right, double bottom) {
27-
return PdfRect(left, top, right - left, bottom - top);
25+
factory PdfRect.fromLTRB(double left, double top, double right, double bottom,
26+
[double? minWidth]) {
27+
return PdfRect(left, top, right - left, bottom - top, minWidth);
2828
}
2929

30-
factory PdfRect.fromPoints(PdfPoint offset, PdfPoint size) {
31-
return PdfRect(offset.x, offset.y, size.x, size.y);
30+
factory PdfRect.fromPoints(PdfPoint offset, PdfPoint size,
31+
[double? minWidth]) {
32+
return PdfRect(offset.x, offset.y, size.x, size.y, minWidth);
3233
}
3334

3435
final double x, y, width, height;
36+
final double? minWidth;
3537

3638
static const PdfRect zero = PdfRect(0, 0, 0, 0);
3739

@@ -70,9 +72,9 @@ class PdfRect {
7072
PdfPoint get bottomRight => PdfPoint(right, top);
7173

7274
/// Returns a new rectangle with edges moved outwards by the given delta.
73-
PdfRect inflate(double delta) {
75+
PdfRect inflate(double delta, [double? minWidth]) {
7476
return PdfRect.fromLTRB(
75-
left - delta, top - delta, right + delta, bottom + delta);
77+
left - delta, top - delta, right + delta, bottom + delta, minWidth);
7678
}
7779

7880
/// Returns a new rectangle with edges moved inwards by the given delta.
@@ -83,12 +85,14 @@ class PdfRect {
8385
double? y,
8486
double? width,
8587
double? height,
88+
double? minWidth,
8689
}) {
8790
return PdfRect(
8891
x ?? this.x,
8992
y ?? this.y,
9093
width ?? this.width,
9194
height ?? this.height,
95+
minWidth ?? this.minWidth,
9296
);
9397
}
9498
}

pdf/lib/src/widgets/basic.dart

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -87,8 +87,12 @@ class Padding extends SingleChildWidget {
8787
child!.layout(context, childConstraints, parentUsesSize: parentUsesSize);
8888
assert(child!.box != null);
8989
box = constraints.constrainRect(
90-
width: child!.box!.width + resolvedPadding.horizontal,
91-
height: child!.box!.height + resolvedPadding.vertical);
90+
width: child!.box!.width + resolvedPadding.horizontal,
91+
height: child!.box!.height + resolvedPadding.vertical,
92+
minWidth: child!.box!.minWidth != null
93+
? child!.box!.minWidth! + resolvedPadding.horizontal
94+
: null,
95+
);
9296
} else {
9397
box = constraints.constrainRect(
9498
width: resolvedPadding.horizontal, height: resolvedPadding.vertical);
@@ -323,12 +327,16 @@ class Align extends SingleChildWidget {
323327
assert(child!.box != null);
324328

325329
box = constraints.constrainRect(
326-
width: shrinkWrapWidth
327-
? child!.box!.width * (widthFactor ?? 1.0)
328-
: double.infinity,
329-
height: shrinkWrapHeight
330-
? child!.box!.height * (heightFactor ?? 1.0)
331-
: double.infinity);
330+
width: shrinkWrapWidth
331+
? child!.box!.width * (widthFactor ?? 1.0)
332+
: double.infinity,
333+
height: shrinkWrapHeight
334+
? child!.box!.height * (heightFactor ?? 1.0)
335+
: double.infinity,
336+
minWidth: child!.box!.minWidth != null && shrinkWrapWidth
337+
? child!.box!.minWidth! * (widthFactor ?? 1.0)
338+
: null,
339+
);
332340
final resolvedAlignment = alignment.resolve(Directionality.of(context));
333341
child!.box = resolvedAlignment.inscribe(child!.box!.size, box!);
334342
} else {

pdf/lib/src/widgets/geometry.dart

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -104,10 +104,13 @@ class BoxConstraints {
104104
return result;
105105
}
106106

107-
PdfRect constrainRect(
108-
{double width = double.infinity, double height = double.infinity}) {
107+
PdfRect constrainRect({
108+
double width = double.infinity,
109+
double height = double.infinity,
110+
double? minWidth,
111+
}) {
109112
final result = PdfPoint(constrainWidth(width), constrainHeight(height));
110-
return PdfRect.fromPoints(PdfPoint.zero, result);
113+
return PdfRect.fromPoints(PdfPoint.zero, result, minWidth);
111114
}
112115

113116
double constrainWidth([double width = double.infinity]) {
@@ -672,6 +675,7 @@ class Alignment extends AlignmentGeometry {
672675
rect.y + halfHeightDelta + y * halfHeightDelta,
673676
size.x,
674677
size.y,
678+
rect.minWidth,
675679
);
676680
}
677681

pdf/lib/src/widgets/table.dart

Lines changed: 35 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -147,10 +147,11 @@ class TableContext extends WidgetContext {
147147
}
148148

149149
class ColumnLayout {
150-
ColumnLayout(this.width, this.flex);
150+
ColumnLayout(this.width, this.flex, [this.minWidth]);
151151

152152
final double? width;
153153
final double? flex;
154+
final double? minWidth;
154155
}
155156

156157
abstract class TableColumnWidth {
@@ -180,7 +181,7 @@ class IntrinsicColumnWidth extends TableColumnWidth {
180181
(child is Expanded
181182
? child.flex.toDouble()
182183
: (child.box!.width == double.infinity ? 1 : 0));
183-
return ColumnLayout(calculatedWidth, childFlex);
184+
return ColumnLayout(calculatedWidth, childFlex, child.box!.minWidth);
184185
}
185186
}
186187

@@ -317,6 +318,7 @@ class Table extends Widget with SpanningWidget {
317318

318319
final List<double?> _widths = <double?>[];
319320
final List<double> _heights = <double>[];
321+
final List<double?> _minWidths = <double>[];
320322

321323
final TableContext _context = TableContext();
322324

@@ -341,6 +343,7 @@ class Table extends Widget with SpanningWidget {
341343
final flex = <double?>[];
342344
_widths.clear();
343345
_heights.clear();
346+
_minWidths.clear();
344347
var index = 0;
345348

346349
for (final row in children) {
@@ -353,11 +356,13 @@ class Table extends Widget with SpanningWidget {
353356
if (flex.length < n + 1) {
354357
flex.add(columnLayout.flex);
355358
_widths.add(columnLayout.width);
359+
_minWidths.add(columnLayout.minWidth ?? 0);
356360
} else {
357361
if (columnLayout.flex! > 0) {
358362
flex[n] = math.max(flex[n]!, columnLayout.flex!);
359363
}
360364
_widths[n] = math.max(_widths[n]!, columnLayout.width!);
365+
_minWidths[n] = math.max(_minWidths[n]!, columnLayout.minWidth ?? 0);
361366
}
362367
n++;
363368
}
@@ -380,10 +385,38 @@ class Table extends Widget with SpanningWidget {
380385
if ((tableWidth == TableWidth.max && totalFlex == 0.0) ||
381386
newWidth < _widths[n]!) {
382387
_widths[n] = newWidth;
388+
_widths[n] = math.max(newWidth, _minWidths[n]!);
383389
}
384390
flexSpace += _widths[n]!;
385391
}
386392
}
393+
394+
if (tableWidth == TableWidth.max && totalFlex == 0.0) {
395+
final totalWidth = flexSpace;
396+
final remainingSpace = constraints.maxWidth - totalWidth;
397+
flexSpace = 0.0;
398+
399+
if (remainingSpace != 0) {
400+
// Calculate the total adjustable width
401+
final adjustableWidth = _widths
402+
.asMap()
403+
.entries
404+
.where((entry) => entry.value! > _minWidths[entry.key]!)
405+
.map((entry) => entry.value! - _minWidths[entry.key]!)
406+
.reduce((a, b) => a + b);
407+
408+
for (var i = 0; i < _widths.length; i++) {
409+
if (_widths[i]! > _minWidths[i]!) {
410+
final proportion =
411+
(_widths[i]! - _minWidths[i]!) / adjustableWidth;
412+
final adjustment = remainingSpace * proportion;
413+
_widths[i] = math.max(_minWidths[i]!, _widths[i]! + adjustment);
414+
}
415+
flexSpace += _widths[i]!;
416+
}
417+
}
418+
}
419+
387420
final spacePerFlex = totalFlex > 0.0
388421
? ((constraints.maxWidth - flexSpace) / totalFlex)
389422
: double.nan;

pdf/lib/src/widgets/text.dart

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -907,6 +907,7 @@ class RichText extends Widget with SpanningWidget {
907907

908908
var top = 0.0;
909909
var bottom = 0.0;
910+
var minWidth = 0.0;
910911

911912
final lines = <_Line>[];
912913
var spanCount = 0;
@@ -953,6 +954,8 @@ class RichText extends Widget with SpanningWidget {
953954
(style.fontSize! * textScaleFactor)) *
954955
(style.fontSize! * textScaleFactor);
955956

957+
minWidth = math.max(minWidth, metrics.width);
958+
956959
if (_softWrap &&
957960
offsetX + metrics.width > constraintWidth + 0.00001) {
958961
if (hyphenation != null) {
@@ -1200,7 +1203,7 @@ class RichText extends Widget with SpanningWidget {
12001203
}
12011204

12021205
box = PdfRect(0, 0, constraints.constrainWidth(width),
1203-
constraints.constrainHeight(offsetY));
1206+
constraints.constrainHeight(offsetY), minWidth);
12041207

12051208
_context
12061209
..endOffset = offsetY - _context.startOffset

0 commit comments

Comments
 (0)