Skip to content
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

Fixes issue #1042 #2778

Merged
merged 3 commits into from
Sep 5, 2024
Merged
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
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
Loading