Skip to content

Fix Mid-word line break inside table #1716

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 12 additions & 8 deletions pdf/lib/src/pdf/rect.dart
Original file line number Diff line number Diff line change
Expand Up @@ -20,18 +20,20 @@ import 'point.dart';

@immutable
class PdfRect {
const PdfRect(this.x, this.y, this.width, this.height);
const PdfRect(this.x, this.y, this.width, this.height, [this.minWidth]);

factory PdfRect.fromLTRB(
double left, double top, double right, double bottom) {
return PdfRect(left, top, right - left, bottom - top);
factory PdfRect.fromLTRB(double left, double top, double right, double bottom,
[double? minWidth]) {
return PdfRect(left, top, right - left, bottom - top, minWidth);
}

factory PdfRect.fromPoints(PdfPoint offset, PdfPoint size) {
return PdfRect(offset.x, offset.y, size.x, size.y);
factory PdfRect.fromPoints(PdfPoint offset, PdfPoint size,
[double? minWidth]) {
return PdfRect(offset.x, offset.y, size.x, size.y, minWidth);
}

final double x, y, width, height;
final double? minWidth;

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

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

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

/// Returns a new rectangle with edges moved inwards by the given delta.
Expand All @@ -83,12 +85,14 @@ class PdfRect {
double? y,
double? width,
double? height,
double? minWidth,
}) {
return PdfRect(
x ?? this.x,
y ?? this.y,
width ?? this.width,
height ?? this.height,
minWidth ?? this.minWidth,
);
}
}
24 changes: 16 additions & 8 deletions pdf/lib/src/widgets/basic.dart
Original file line number Diff line number Diff line change
Expand Up @@ -87,8 +87,12 @@ class Padding extends SingleChildWidget {
child!.layout(context, childConstraints, parentUsesSize: parentUsesSize);
assert(child!.box != null);
box = constraints.constrainRect(
width: child!.box!.width + resolvedPadding.horizontal,
height: child!.box!.height + resolvedPadding.vertical);
width: child!.box!.width + resolvedPadding.horizontal,
height: child!.box!.height + resolvedPadding.vertical,
minWidth: child!.box!.minWidth != null
? child!.box!.minWidth! + resolvedPadding.horizontal
: null,
);
} else {
box = constraints.constrainRect(
width: resolvedPadding.horizontal, height: resolvedPadding.vertical);
Expand Down Expand Up @@ -323,12 +327,16 @@ class Align extends SingleChildWidget {
assert(child!.box != null);

box = constraints.constrainRect(
width: shrinkWrapWidth
? child!.box!.width * (widthFactor ?? 1.0)
: double.infinity,
height: shrinkWrapHeight
? child!.box!.height * (heightFactor ?? 1.0)
: double.infinity);
width: shrinkWrapWidth
? child!.box!.width * (widthFactor ?? 1.0)
: double.infinity,
height: shrinkWrapHeight
? child!.box!.height * (heightFactor ?? 1.0)
: double.infinity,
minWidth: child!.box!.minWidth != null && shrinkWrapWidth
? child!.box!.minWidth! * (widthFactor ?? 1.0)
: null,
);
final resolvedAlignment = alignment.resolve(Directionality.of(context));
child!.box = resolvedAlignment.inscribe(child!.box!.size, box!);
} else {
Expand Down
10 changes: 7 additions & 3 deletions pdf/lib/src/widgets/geometry.dart
Original file line number Diff line number Diff line change
Expand Up @@ -104,10 +104,13 @@ class BoxConstraints {
return result;
}

PdfRect constrainRect(
{double width = double.infinity, double height = double.infinity}) {
PdfRect constrainRect({
double width = double.infinity,
double height = double.infinity,
double? minWidth,
}) {
final result = PdfPoint(constrainWidth(width), constrainHeight(height));
return PdfRect.fromPoints(PdfPoint.zero, result);
return PdfRect.fromPoints(PdfPoint.zero, result, minWidth);
}

double constrainWidth([double width = double.infinity]) {
Expand Down Expand Up @@ -672,6 +675,7 @@ class Alignment extends AlignmentGeometry {
rect.y + halfHeightDelta + y * halfHeightDelta,
size.x,
size.y,
rect.minWidth,
);
}

Expand Down
43 changes: 39 additions & 4 deletions pdf/lib/src/widgets/table.dart
Original file line number Diff line number Diff line change
Expand Up @@ -147,10 +147,11 @@ class TableContext extends WidgetContext {
}

class ColumnLayout {
ColumnLayout(this.width, this.flex);
ColumnLayout(this.width, this.flex, [this.minWidth]);

final double? width;
final double? flex;
final double? minWidth;
}

abstract class TableColumnWidth {
Expand Down Expand Up @@ -180,7 +181,7 @@ class IntrinsicColumnWidth extends TableColumnWidth {
(child is Expanded
? child.flex.toDouble()
: (child.box!.width == double.infinity ? 1 : 0));
return ColumnLayout(calculatedWidth, childFlex);
return ColumnLayout(calculatedWidth, childFlex, child.box!.minWidth);
}
}

Expand All @@ -204,7 +205,9 @@ class FlexColumnWidth extends TableColumnWidth {
@override
ColumnLayout layout(
Widget child, Context context, BoxConstraints? constraints) {
return ColumnLayout(0, flex);
child.layout(context, const BoxConstraints());
assert(child.box != null);
return ColumnLayout(0, flex, child.box!.minWidth);
}
}

Expand Down Expand Up @@ -317,6 +320,7 @@ class Table extends Widget with SpanningWidget {

final List<double?> _widths = <double?>[];
final List<double> _heights = <double>[];
final List<double?> _minWidths = <double>[];

final TableContext _context = TableContext();

Expand All @@ -341,6 +345,7 @@ class Table extends Widget with SpanningWidget {
final flex = <double?>[];
_widths.clear();
_heights.clear();
_minWidths.clear();
var index = 0;

for (final row in children) {
Expand All @@ -353,11 +358,13 @@ class Table extends Widget with SpanningWidget {
if (flex.length < n + 1) {
flex.add(columnLayout.flex);
_widths.add(columnLayout.width);
_minWidths.add(columnLayout.minWidth ?? 0);
} else {
if (columnLayout.flex! > 0) {
flex[n] = math.max(flex[n]!, columnLayout.flex!);
}
_widths[n] = math.max(_widths[n]!, columnLayout.width!);
_minWidths[n] = math.max(_minWidths[n]!, columnLayout.minWidth ?? 0);
}
n++;
}
Expand All @@ -380,18 +387,46 @@ class Table extends Widget with SpanningWidget {
if ((tableWidth == TableWidth.max && totalFlex == 0.0) ||
newWidth < _widths[n]!) {
_widths[n] = newWidth;
_widths[n] = math.max(newWidth, _minWidths[n]!);
}
flexSpace += _widths[n]!;
}
}

if (tableWidth == TableWidth.max && totalFlex == 0.0) {
final totalWidth = flexSpace;
final remainingSpace = constraints.maxWidth - totalWidth;
flexSpace = 0.0;

if (remainingSpace != 0) {
// Calculate the total adjustable width
final adjustableWidth = _widths
.asMap()
.entries
.where((entry) => entry.value! > _minWidths[entry.key]!)
.map((entry) => entry.value! - _minWidths[entry.key]!)
.reduce((a, b) => a + b);

for (var i = 0; i < _widths.length; i++) {
if (_widths[i]! > _minWidths[i]!) {
final proportion =
(_widths[i]! - _minWidths[i]!) / adjustableWidth;
final adjustment = remainingSpace * proportion;
_widths[i] = math.max(_minWidths[i]!, _widths[i]! + adjustment);
}
flexSpace += _widths[i]!;
}
}
}

final spacePerFlex = totalFlex > 0.0
? ((constraints.maxWidth - flexSpace) / totalFlex)
: double.nan;

for (var n = 0; n < _widths.length; n++) {
if (flex[n]! > 0.0) {
final newWidth = spacePerFlex * flex[n]!;
_widths[n] = newWidth;
_widths[n] = math.max(newWidth, _minWidths[n]!);
}
}
}
Expand Down
5 changes: 4 additions & 1 deletion pdf/lib/src/widgets/text.dart
Original file line number Diff line number Diff line change
Expand Up @@ -907,6 +907,7 @@ class RichText extends Widget with SpanningWidget {

var top = 0.0;
var bottom = 0.0;
var minWidth = 0.0;

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

minWidth = math.max(minWidth, metrics.width);

if (_softWrap &&
offsetX + metrics.width > constraintWidth + 0.00001) {
if (hyphenation != null) {
Expand Down Expand Up @@ -1200,7 +1203,7 @@ class RichText extends Widget with SpanningWidget {
}

box = PdfRect(0, 0, constraints.constrainWidth(width),
constraints.constrainHeight(offsetY));
constraints.constrainHeight(offsetY), minWidth);

_context
..endOffset = offsetY - _context.startOffset
Expand Down