devextreme
Version:
HTML5 JavaScript Component Suite for Responsive Web Development
175 lines (170 loc) • 8.12 kB
JavaScript
/**
* DevExtreme (cjs/exporter/jspdf/common/rows_splitting.js)
* Version: 24.2.6
* Build date: Mon Mar 17 2025
*
* Copyright (c) 2012 - 2025 Developer Express Inc. ALL RIGHTS RESERVED
* Read about DevExtreme licensing here: https://js.devexpress.com/Licensing/
*/
;
exports.splitByPages = splitByPages;
var _type = require("../../../core/utils/type");
var _pdf_utils = require("./pdf_utils");
var _draw_utils = require("./draw_utils");
var _get_multipage_row_pages = require("./rows_spliting_utils/get_multipage_row_pages");
var _create_on_split_multipage_row = require("./rows_spliting_utils/create_on_split_multipage_row");
function _extends() {
return _extends = Object.assign ? Object.assign.bind() : function(n) {
for (var e = 1; e < arguments.length; e++) {
var t = arguments[e];
for (var r in t) {
({}).hasOwnProperty.call(t, r) && (n[r] = t[r])
}
}
return n
}, _extends.apply(null, arguments)
}
const COORDINATE_EPSILON = .001;
function convertToCellsArray(rows) {
return [].concat.apply([], rows.map((rowInfo => rowInfo.cells.filter((cell => !(0, _type.isDefined)(cell.pdfCell.isMerged))).map((cellInfo => Object.assign({}, cellInfo.pdfCell._rect, {
sourceCellInfo: _extends({}, cellInfo.pdfCell, {
gridCell: cellInfo.gridCell
})
}))))))
}
function splitByPages(doc, rowsInfo, options, onSeparateRectHorizontally, onSeparateRectVertically) {
if (0 === rowsInfo.length) {
return [
[]
]
}
const maxBottomRight = {
x: (0, _pdf_utils.getPageWidth)(doc) - options.margin.right,
y: (0, _pdf_utils.getPageHeight)(doc) - options.margin.bottom
};
const headerRows = rowsInfo.filter((r => "header" === r.rowType));
const headerHeight = headerRows.reduce(((accumulator, row) => accumulator + row.height), 0);
const verticallyPages = splitRectsByPages(convertToCellsArray(rowsInfo), options.margin.top, "y", "h", ((isFirstPage, currentCoordinate) => {
const additionalHeight = !isFirstPage && options.repeatHeaders ? headerHeight : 0;
return (0, _draw_utils.roundToThreeDecimals)(currentCoordinate + additionalHeight) <= (0, _draw_utils.roundToThreeDecimals)(maxBottomRight.y)
}), ((rect, currentPageMaxRectCoordinate, currentPageRects, rectsToSplit) => {
const args = {
sourceRect: rect,
topRect: {
x: rect.x,
y: rect.y,
w: rect.w,
h: currentPageMaxRectCoordinate - rect.y
},
bottomRect: {
x: rect.x,
y: currentPageMaxRectCoordinate,
w: rect.w,
h: rect.h - (currentPageMaxRectCoordinate - rect.y)
}
};
onSeparateRectVertically(args);
currentPageRects.push(args.topRect);
rectsToSplit.push(args.bottomRect)
}), (0, _create_on_split_multipage_row.createOnSplitMultiPageRow)(doc, options, headerHeight, maxBottomRight));
if (options.repeatHeaders) {
for (let i = 1; i < verticallyPages.length; i++) {
verticallyPages[i].forEach((rect => rect.y += headerHeight));
const headerCells = convertToCellsArray(headerRows);
headerCells.forEach((cell => {
cell.y -= options.topLeft.y
}));
verticallyPages[i] = [...headerCells, ...verticallyPages[i]]
}
}
let pageIndex = 0;
while (pageIndex < verticallyPages.length) {
const horizontallyPages = splitRectsByPages(verticallyPages[pageIndex], options.margin.left, "x", "w", ((pagesLength, currentCoordinate) => (0, _draw_utils.roundToThreeDecimals)(currentCoordinate) <= (0, _draw_utils.roundToThreeDecimals)(maxBottomRight.x)), ((rect, currentPageMaxRectCoordinate, currentPageRects, rectsToSplit) => {
const args = {
sourceRect: rect,
leftRect: {
x: rect.x,
y: rect.y,
w: currentPageMaxRectCoordinate - rect.x,
h: rect.h
},
rightRect: {
x: currentPageMaxRectCoordinate,
y: rect.y,
w: rect.w - (currentPageMaxRectCoordinate - rect.x),
h: rect.h
}
};
onSeparateRectHorizontally(args);
currentPageRects.push(args.leftRect);
rectsToSplit.push(args.rightRect)
}));
if (horizontallyPages.length > 1) {
verticallyPages.splice(pageIndex, 1, ...horizontallyPages);
pageIndex += horizontallyPages.length
} else {
pageIndex += 1
}
}
return verticallyPages.map((rects => rects.map((rect => Object.assign({}, rect.sourceCellInfo, {
_rect: rect
})))))
}
function splitRectsByPages(rects, marginValue, coordinate, dimension, isFitToPage, onSeparateCallback, onSplitMultiPageRow) {
const pages = [];
const rectsToSplit = [...rects];
const isFitToPageForMultiPageRow = (isFirstPage, rectHeight) => isFitToPage(isFirstPage, rectHeight + marginValue);
while (rectsToSplit.length > 0) {
let currentPageMaxRectCoordinate = 0;
const currentPageRects = rectsToSplit.filter((rect => {
const currentRectCoordinate = rect[coordinate] + rect[dimension];
if (isFitToPage(0 === pages.length, currentRectCoordinate)) {
if (currentPageMaxRectCoordinate <= currentRectCoordinate) {
currentPageMaxRectCoordinate = currentRectCoordinate
}
return true
} else {
return false
}
}));
const isCurrentPageContainsOnlyHeader = (0, _get_multipage_row_pages.checkPageContainsOnlyHeader)(currentPageRects, 0 === pages.length);
const multiPageRowPages = (0, _get_multipage_row_pages.getMultiPageRowPages)(currentPageRects, rectsToSplit, isCurrentPageContainsOnlyHeader, onSplitMultiPageRow, isFitToPageForMultiPageRow);
const rectsToSeparate = rectsToSplit.filter((rect => {
const currentRectLeft = rect[coordinate];
const currentRectRight = rect[coordinate] + rect[dimension];
return currentPageMaxRectCoordinate - currentRectLeft > .001 && currentRectRight - currentPageMaxRectCoordinate > .001
}));
rectsToSeparate.forEach((rect => {
onSeparateCallback(rect, currentPageMaxRectCoordinate, currentPageRects, rectsToSplit);
const index = rectsToSplit.indexOf(rect);
if (-1 !== index) {
rectsToSplit.splice(index, 1)
}
}));
currentPageRects.forEach((rect => {
const index = rectsToSplit.indexOf(rect);
if (-1 !== index) {
rectsToSplit.splice(index, 1)
}
}));
rectsToSplit.forEach((rect => {
rect[coordinate] = (0, _type.isDefined)(currentPageMaxRectCoordinate) ? rect[coordinate] - currentPageMaxRectCoordinate + marginValue : rect[coordinate]
}));
const firstPageContainsHeaderAndMultiPageRow = isCurrentPageContainsOnlyHeader && multiPageRowPages.length > 0;
if (firstPageContainsHeaderAndMultiPageRow) {
const [firstPage, ...restOfPages] = multiPageRowPages;
pages.push([...currentPageRects, ...firstPage]);
pages.push(...restOfPages)
} else if (currentPageRects.length > 0) {
pages.push(currentPageRects);
pages.push(...multiPageRowPages)
} else if (multiPageRowPages.length > 0) {
pages.push(...multiPageRowPages);
pages.push(rectsToSplit)
} else {
pages.push(rectsToSplit);
break
}
}
return pages
}