Skip to content

Commit

Permalink
Fixes issue #1042 (#2778)
Browse files Browse the repository at this point in the history
* Fixes issue #1042

* Fixes unit tests that broke after last commit

---------

Co-authored-by: fe-cj <[email protected]>
  • Loading branch information
fe-cj and fe-cj authored Sep 5, 2024
1 parent de526ac commit aff4a14
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 @@ -65,10 +65,10 @@ class DocumentContext extends EventEmitter {
}
}

markEnding(endingCell, originalXOffset) {
markEnding(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 @@ -476,7 +476,7 @@ class LayoutBuilder {
}

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

function gapArray(gap) {
Expand Down Expand Up @@ -510,7 +510,7 @@ class LayoutBuilder {
return null;
}

processRow(columns, widths, gaps, tableBody, tableRow, height) {
processRow(dontBreakRows, columns, widths, gaps, tableBody, tableRow, height) {
const updatePageBreakData = (page, prevY) => {
let pageDesc;
// Find page break data for this row and page
Expand Down Expand Up @@ -571,6 +571,7 @@ class LayoutBuilder {
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 @@ -588,10 +589,17 @@ class LayoutBuilder {

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

if (!column._span) {
this.processNode(column);
addAll(positions, column.positions);
} else if (column._columnEndingContext) {
let 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;
}
let 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 @@ -600,7 +608,7 @@ class LayoutBuilder {
}
// row-span ending
// Recover the context after processing the rowspanned cell
this.writer.context().markEnding(column, originalXOffset);
this.writer.context().markEnding(column, originalXOffset, discountY);
}
}

Expand Down Expand Up @@ -708,6 +716,16 @@ class LayoutBuilder {

let rowHeights = tableNode.table.heights;
for (let 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);

let height;
Expand All @@ -723,7 +741,7 @@ class LayoutBuilder {
height = undefined;
}

let result = this.processRow(tableNode.table.body[i], tableNode.table.widths, tableNode._offsets.offsets, tableNode.table.body, i, height);
let 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/unit/LayoutBuilder.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -1679,15 +1679,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 @@ -1697,7 +1697,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 @@ -1708,14 +1708,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 @@ -1727,7 +1727,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 @@ -1739,7 +1739,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 aff4a14

Please sign in to comment.