Skip to content

Commit

Permalink
backport PR #2778
Browse files Browse the repository at this point in the history
  • Loading branch information
liborm85 committed Sep 5, 2024
1 parent cf8458f commit 721dde0
Show file tree
Hide file tree
Showing 3 changed files with 31 additions and 13 deletions.
4 changes: 2 additions & 2 deletions src/documentContext.js
Original file line number Diff line number Diff line change
Expand Up @@ -68,10 +68,10 @@ DocumentContext.prototype.calculateBottomMost = function (destContext, endingCel
}
};

DocumentContext.prototype.markEnding = function (endingCell, originalXOffset) {
DocumentContext.prototype.markEnding = function (endingCell, originalXOffset, discountY) {
this.page = endingCell._columnEndingContext.page;
this.x = endingCell._columnEndingContext.x + originalXOffset;
this.y = endingCell._columnEndingContext.y;
this.y = endingCell._columnEndingContext.y - discountY;
this.availableWidth = endingCell._columnEndingContext.availableWidth;
this.availableHeight = endingCell._columnEndingContext.availableHeight;
this.lastColumnWidth = endingCell._columnEndingContext.lastColumnWidth;
Expand Down
26 changes: 22 additions & 4 deletions src/layoutBuilder.js
Original file line number Diff line number Diff line change
Expand Up @@ -491,7 +491,7 @@ LayoutBuilder.prototype.processColumns = function (columnNode) {
}

ColumnCalculator.buildColumnWidths(columns, availableWidth);
var result = this.processRow(columns, columns, gaps);
var result = this.processRow(false, columns, columns, gaps);
addAll(columnNode.positions, result.positions);


Expand Down Expand Up @@ -526,7 +526,7 @@ LayoutBuilder.prototype.findStartingSpanCell = function (arr, i) {
return null;
}

LayoutBuilder.prototype.processRow = function (columns, widths, gaps, tableBody, tableRow, height) {
LayoutBuilder.prototype.processRow = function (dontBreakRows, columns, widths, gaps, tableBody, tableRow, height) {
var self = this;
var pageBreaks = [], positions = [];

Expand All @@ -551,6 +551,7 @@ LayoutBuilder.prototype.processRow = function (columns, widths, gaps, tableBody,
if (endingCell) {
// We store a reference of the ending cell in the first cell of the rowspan
column._endingCell = endingCell;
column._endingCell._startingRowSpanY = column._startingRowSpanY;
}

// Check if exists and retrieve the cell that started the rowspan in case we are in the cell just after
Expand All @@ -568,10 +569,17 @@ LayoutBuilder.prototype.processRow = function (columns, widths, gaps, tableBody,

// We pass the endingSpanCell reference to store the context just after processing rowspan cell
self.writer.context().beginColumn(width, leftOffset, endingSpanCell);

if (!column._span) {
self.processNode(column);
addAll(positions, column.positions);
} else if (column._columnEndingContext) {
var discountY = 0;
if (dontBreakRows) {
// Calculate how many points we have to discount to Y when dontBreakRows and rowSpan are combined
const ctxBeforeRowSpanLastRow = this.writer.contextStack[this.writer.contextStack.length - 1];
discountY = ctxBeforeRowSpanLastRow.y - column._startingRowSpanY;
}
var originalXOffset = 0;
// If context was saved from an unbreakable block and we are not in an unbreakable block anymore
// We have to sum the originalX (X before starting unbreakable block) to X
Expand All @@ -580,7 +588,7 @@ LayoutBuilder.prototype.processRow = function (columns, widths, gaps, tableBody,
}
// row-span ending
// Recover the context after processing the rowspanned cell
self.writer.context().markEnding(column, originalXOffset);
self.writer.context().markEnding(column, originalXOffset, discountY);
}
}

Expand Down Expand Up @@ -720,6 +728,16 @@ LayoutBuilder.prototype.processTable = function (tableNode) {

var rowHeights = tableNode.table.heights;
for (var i = 0, l = tableNode.table.body.length; i < l; i++) {
// if dontBreakRows and row starts a rowspan
// we store the 'y' of the beginning of each rowSpan
if (processor.dontBreakRows) {
tableNode.table.body[i].forEach(cell => {
if (cell.rowSpan && cell.rowSpan > 1) {
cell._startingRowSpanY = this.writer.context().y;
}
});
}

processor.beginRow(i, this.writer);

var height;
Expand All @@ -735,7 +753,7 @@ LayoutBuilder.prototype.processTable = function (tableNode) {
height = undefined;
}

var result = this.processRow(tableNode.table.body[i], tableNode.table.widths, tableNode._offsets.offsets, tableNode.table.body, i, height);
var result = this.processRow(processor.dontBreakRows, tableNode.table.body[i], tableNode.table.widths, tableNode._offsets.offsets, tableNode.table.body, i, height);
addAll(tableNode.positions, result.positions);

processor.endRow(i, this.writer, result.pageBreaks);
Expand Down
14 changes: 7 additions & 7 deletions tests/layoutBuilder.js
Original file line number Diff line number Diff line change
Expand Up @@ -1684,15 +1684,15 @@ describe('LayoutBuilder', function () {
it('should return an empty array if no page breaks occur', function () {
var doc = createTable(1, 0);

var result = builder2.processRow(doc.table.body[0], doc.table.widths, doc._offsets.offsets, doc.table.body, 0);
var result = builder2.processRow(false, doc.table.body[0], doc.table.widths, doc._offsets.offsets, doc.table.body, 0);

assert(result.pageBreaks instanceof Array);
assert.equal(result.pageBreaks.length, 0);
});

it('on page break should return an entry with ending/starting positions', function () {
var doc = createTable(0, 1, 10, 5, 5);
var result = builder2.processRow(doc.table.body[0], doc.table.widths, doc._offsets.offsets, doc.table.body, 0);
var result = builder2.processRow(false, doc.table.body[0], doc.table.widths, doc._offsets.offsets, doc.table.body, 0);

assert(result.pageBreaks instanceof Array);
assert.equal(result.pageBreaks.length, 1);
Expand All @@ -1702,7 +1702,7 @@ describe('LayoutBuilder', function () {

it('on page break should return an entry with ending/starting positions 2', function () {
var doc = createTable(0, 1, 10, 5);
var result = builder2.processRow(doc.table.body[0], doc.table.widths, doc._offsets.offsets, doc.table.body, 0);
var result = builder2.processRow(false, doc.table.body[0], doc.table.widths, doc._offsets.offsets, doc.table.body, 0);

assert(result.pageBreaks instanceof Array);
assert.equal(result.pageBreaks.length, 1);
Expand All @@ -1712,14 +1712,14 @@ describe('LayoutBuilder', function () {

it('on multi-pass page break (columns or table columns) should treat bottom-most page-break as the ending position ', function () {
var doc = createTable(0, 1, 10, 5, 7);
var result = builder2.processRow(doc.table.body[0], doc.table.widths, doc._offsets.offsets, doc.table.body, 0);
var result = builder2.processRow(false, doc.table.body[0], doc.table.widths, doc._offsets.offsets, doc.table.body, 0);

assert.equal(result.pageBreaks[0].prevY, 40 + 12 * 7);
});

it('on multiple page breaks (more than 2 pages), should return all entries with ending/starting positions', function () {
var doc = createTable(0, 1, 100, 90, 90);
var result = builder2.processRow(doc.table.body[0], doc.table.widths, doc._offsets.offsets, doc.table.body, 0);
var result = builder2.processRow(false, doc.table.body[0], doc.table.widths, doc._offsets.offsets, doc.table.body, 0);

assert(result.pageBreaks instanceof Array);
assert.equal(result.pageBreaks.length, 2);
Expand All @@ -1731,7 +1731,7 @@ describe('LayoutBuilder', function () {

it('on multiple page breaks (more than 2 pages), should return all entries with ending/starting positions 2', function () {
var doc = createTable(0, 1, 100, 90);
var result = builder2.processRow(doc.table.body[0], doc.table.widths, doc._offsets.offsets, doc.table.body, 0);
var result = builder2.processRow(false, doc.table.body[0], doc.table.widths, doc._offsets.offsets, doc.table.body, 0);

assert(result.pageBreaks instanceof Array);
assert.equal(result.pageBreaks.length, 2);
Expand All @@ -1743,7 +1743,7 @@ describe('LayoutBuilder', function () {

it('on multiple and multi-pass page breaks should calculate bottom-most endings for every page', function () {
var doc = createTable(0, 1, 100, 90, 92);
var result = builder2.processRow(doc.table.body[0], doc.table.widths, doc._offsets.offsets, doc.table.body, 0);
var result = builder2.processRow(false, doc.table.body[0], doc.table.widths, doc._offsets.offsets, doc.table.body, 0);

assert(result.pageBreaks instanceof Array);
assert.equal(result.pageBreaks.length, 2);
Expand Down

0 comments on commit 721dde0

Please sign in to comment.