Comparing version
# Changelog | ||
## 0.3.0-beta.18 - 2025-05-09 | ||
- Added `section` node | ||
- Fixed crash that occurred when using automatic page height | ||
- Fixed text overflow with some non-wrappable texts | ||
## 0.3.0-beta.17 - 2025-04-29 | ||
@@ -4,0 +10,0 @@ |
@@ -34,2 +34,5 @@ "use strict"; | ||
} | ||
measureBlock(node) { | ||
return this.measureNode(node); | ||
} | ||
measureNode(node) { | ||
@@ -39,3 +42,5 @@ return this.styleStack.auto(node, () => { | ||
node._margin = (0, _node.getNodeMargin)(node, this.styleStack); | ||
if (node.columns) { | ||
if (node.section) { | ||
return extendMargins(this.measureSection(node)); | ||
} else if (node.columns) { | ||
return extendMargins(this.measureColumns(node)); | ||
@@ -428,2 +433,8 @@ } else if (node.stack) { | ||
} | ||
measureSection(node) { | ||
// TODO: properties | ||
node.section = this.measureNode(node.section); | ||
return node; | ||
} | ||
measureColumns(node) { | ||
@@ -430,0 +441,0 @@ let columns = node.columns; |
@@ -25,5 +25,11 @@ "use strict"; | ||
this.nodeReferences = []; | ||
return this.preprocessNode(docStructure); | ||
return this.preprocessNode(docStructure, true); | ||
} | ||
preprocessNode(node) { | ||
preprocessBlock(node) { | ||
this.parentNode = null; | ||
this.tocs = []; | ||
this.nodeReferences = []; | ||
return this.preprocessNode(node); | ||
} | ||
preprocessNode(node, isSectionAllowed = false) { | ||
// expand shortcuts and casting values | ||
@@ -43,6 +49,11 @@ if (Array.isArray(node)) { | ||
} | ||
if (node.columns) { | ||
if (node.section) { | ||
if (!isSectionAllowed) { | ||
throw new Error(`Incorrect document structure, section node is only allowed at the root level of document structure: ${(0, _node.stringifyNode)(node)}`); | ||
} | ||
return this.preprocessSection(node); | ||
} else if (node.columns) { | ||
return this.preprocessColumns(node); | ||
} else if (node.stack) { | ||
return this.preprocessVerticalContainer(node); | ||
return this.preprocessVerticalContainer(node, isSectionAllowed); | ||
} else if (node.ul) { | ||
@@ -74,2 +85,6 @@ return this.preprocessList(node); | ||
} | ||
preprocessSection(node) { | ||
node.section = this.preprocessNode(node.section); | ||
return node; | ||
} | ||
preprocessColumns(node) { | ||
@@ -82,6 +97,6 @@ let columns = node.columns; | ||
} | ||
preprocessVerticalContainer(node) { | ||
preprocessVerticalContainer(node, isSectionAllowed) { | ||
let items = node.stack; | ||
for (let i = 0, l = items.length; i < l; i++) { | ||
items[i] = this.preprocessNode(items[i]); | ||
items[i] = this.preprocessNode(items[i], isSectionAllowed); | ||
} | ||
@@ -88,0 +103,0 @@ return node; |
@@ -207,3 +207,3 @@ "use strict"; | ||
let pageSize = getPageSize(this.getCurrentPage(), pageOrientation); | ||
this.addPage(pageSize); | ||
this.addPage(pageSize, null, this.getCurrentPage().customProperties); | ||
if (currentPageOrientation === pageSize.orientation) { | ||
@@ -223,3 +223,3 @@ this.availableWidth = currentAvailableWidth; | ||
} | ||
addPage(pageSize, pageMargin = null) { | ||
addPage(pageSize, pageMargin = null, customProperties = {}) { | ||
if (pageMargin !== null) { | ||
@@ -233,3 +233,4 @@ this.pageMargins = pageMargin; | ||
pageSize: pageSize, | ||
pageMargins: this.pageMargins | ||
pageMargins: this.pageMargins, | ||
customProperties: customProperties | ||
}; | ||
@@ -240,3 +241,3 @@ this.pages.push(page); | ||
this.initializePage(); | ||
this.emit('pageAdded'); | ||
this.emit('pageAdded', page); | ||
return page; | ||
@@ -243,0 +244,0 @@ } |
@@ -135,2 +135,10 @@ "use strict"; | ||
tryLayoutDocument(docStructure, pdfDocument, styleDictionary, defaultStyle, background, header, footer, watermark) { | ||
const isNecessaryAddFirstPage = docStructure => { | ||
if (docStructure.stack && docStructure.stack.length > 0 && docStructure.stack[0].section) { | ||
return false; | ||
} else if (docStructure.section) { | ||
return false; | ||
} | ||
return true; | ||
}; | ||
this.linearNodeList = []; | ||
@@ -140,11 +148,15 @@ docStructure = this.docPreprocessor.preprocessDocument(docStructure); | ||
this.writer = new _PageElementWriter.default(new _DocumentContext.default()); | ||
this.writer.context().addListener('pageAdded', () => { | ||
this.addBackground(background); | ||
this.writer.context().addListener('pageAdded', page => { | ||
let backgroundGetter = background; | ||
if (page.customProperties['background'] || page.customProperties['background'] === null) { | ||
backgroundGetter = page.customProperties['background']; | ||
} | ||
this.addBackground(backgroundGetter); | ||
}); | ||
this.writer.addPage(this.pageSize, null, this.pageMargins); | ||
if (isNecessaryAddFirstPage(docStructure)) { | ||
this.writer.addPage(this.pageSize, null, this.pageMargins); | ||
} | ||
this.processNode(docStructure); | ||
this.addHeadersAndFooters(header, footer); | ||
if (watermark != null) { | ||
this.addWatermark(watermark, pdfDocument, defaultStyle); | ||
} | ||
this.addWatermark(watermark, pdfDocument, defaultStyle); | ||
return { | ||
@@ -162,4 +174,4 @@ pages: this.writer.context().pages, | ||
this.writer.beginUnbreakableBlock(pageSize.width, pageSize.height); | ||
pageBackground = this.docPreprocessor.preprocessDocument(pageBackground); | ||
this.processNode(this.docMeasure.measureDocument(pageBackground)); | ||
pageBackground = this.docPreprocessor.preprocessBlock(pageBackground); | ||
this.processNode(this.docMeasure.measureBlock(pageBackground)); | ||
this.writer.commitUnbreakableBlock(0, 0); | ||
@@ -169,12 +181,20 @@ context.backgroundLength[context.page] += pageBackground.positions.length; | ||
} | ||
addDynamicRepeatable(nodeGetter, sizeFunction) { | ||
addDynamicRepeatable(nodeGetter, sizeFunction, customPropertyName) { | ||
let pages = this.writer.context().pages; | ||
for (let pageIndex = 0, l = pages.length; pageIndex < l; pageIndex++) { | ||
this.writer.context().page = pageIndex; | ||
let node = nodeGetter(pageIndex + 1, l, this.writer.context().pages[pageIndex].pageSize); | ||
let customProperties = this.writer.context().getCurrentPage().customProperties; | ||
let pageNodeGetter = nodeGetter; | ||
if (customProperties[customPropertyName] || customProperties[customPropertyName] === null) { | ||
pageNodeGetter = customProperties[customPropertyName]; | ||
} | ||
if (typeof pageNodeGetter === 'undefined' || pageNodeGetter === null) { | ||
continue; | ||
} | ||
let node = pageNodeGetter(pageIndex + 1, l, this.writer.context().pages[pageIndex].pageSize); | ||
if (node) { | ||
let sizes = sizeFunction(this.writer.context().getCurrentPage().pageSize, this.writer.context().getCurrentPage().pageMargins); | ||
this.writer.beginUnbreakableBlock(sizes.width, sizes.height); | ||
node = this.docPreprocessor.preprocessDocument(node); | ||
this.processNode(this.docMeasure.measureDocument(node)); | ||
node = this.docPreprocessor.preprocessBlock(node); | ||
this.processNode(this.docMeasure.measureBlock(node)); | ||
this.writer.commitUnbreakableBlock(sizes.x, sizes.y); | ||
@@ -197,23 +217,26 @@ } | ||
}); | ||
if (header) { | ||
this.addDynamicRepeatable(header, headerSizeFct); | ||
} | ||
if (footer) { | ||
this.addDynamicRepeatable(footer, footerSizeFct); | ||
} | ||
this.addDynamicRepeatable(header, headerSizeFct, 'header'); | ||
this.addDynamicRepeatable(footer, footerSizeFct, 'footer'); | ||
} | ||
addWatermark(watermark, pdfDocument, defaultStyle) { | ||
if ((0, _variableType.isString)(watermark)) { | ||
watermark = { | ||
'text': watermark | ||
}; | ||
} | ||
if (!watermark.text) { | ||
// empty watermark text | ||
return; | ||
} | ||
let pages = this.writer.context().pages; | ||
for (let i = 0, l = pages.length; i < l; i++) { | ||
let pageWatermark = watermark; | ||
if (pages[i].customProperties['watermark'] || pages[i].customProperties['watermark'] === null) { | ||
pageWatermark = pages[i].customProperties['watermark']; | ||
} | ||
if (pageWatermark === undefined || pageWatermark === null) { | ||
continue; | ||
} | ||
if ((0, _variableType.isString)(pageWatermark)) { | ||
pageWatermark = { | ||
'text': pageWatermark | ||
}; | ||
} | ||
if (!pageWatermark.text) { | ||
// empty watermark text | ||
continue; | ||
} | ||
pages[i].watermark = getWatermarkObject({ | ||
...watermark | ||
...pageWatermark | ||
}, pages[i].pageSize, pdfDocument, defaultStyle); | ||
@@ -399,2 +422,4 @@ } | ||
this.processVerticalContainer(node); | ||
} else if (node.section) { | ||
this.processSection(node); | ||
} else if (node.columns) { | ||
@@ -444,2 +469,58 @@ this.processColumns(node); | ||
// section | ||
processSection(sectionNode) { | ||
// TODO: properties | ||
let page = this.writer.context().getCurrentPage(); | ||
if (!page || page && page.items.length) { | ||
// move to new empty page | ||
// page definition inherit from current page | ||
if (sectionNode.pageSize === 'inherit') { | ||
sectionNode.pageSize = page ? { | ||
width: page.pageSize.width, | ||
height: page.pageSize.height | ||
} : undefined; | ||
} | ||
if (sectionNode.pageOrientation === 'inherit') { | ||
sectionNode.pageOrientation = page ? page.pageSize.orientation : undefined; | ||
} | ||
if (sectionNode.pageMargins === 'inherit') { | ||
sectionNode.pageMargins = page ? page.pageMargins : undefined; | ||
} | ||
if (sectionNode.header === 'inherit') { | ||
sectionNode.header = page ? page.customProperties.header : undefined; | ||
} | ||
if (sectionNode.footer === 'inherit') { | ||
sectionNode.footer = page ? page.customProperties.footer : undefined; | ||
} | ||
if (sectionNode.background === 'inherit') { | ||
sectionNode.background = page ? page.customProperties.background : undefined; | ||
} | ||
if (sectionNode.watermark === 'inherit') { | ||
sectionNode.watermark = page ? page.customProperties.watermark : undefined; | ||
} | ||
if (sectionNode.header && typeof sectionNode.header !== 'function' && sectionNode.header !== null) { | ||
sectionNode.header = (0, _tools.convertToDynamicContent)(sectionNode.header); | ||
} | ||
if (sectionNode.footer && typeof sectionNode.footer !== 'function' && sectionNode.footer !== null) { | ||
sectionNode.footer = (0, _tools.convertToDynamicContent)(sectionNode.footer); | ||
} | ||
let customProperties = {}; | ||
if (typeof sectionNode.header !== 'undefined') { | ||
customProperties.header = sectionNode.header; | ||
} | ||
if (typeof sectionNode.footer !== 'undefined') { | ||
customProperties.footer = sectionNode.footer; | ||
} | ||
if (typeof sectionNode.background !== 'undefined') { | ||
customProperties.background = sectionNode.background; | ||
} | ||
if (typeof sectionNode.watermark !== 'undefined') { | ||
customProperties.watermark = sectionNode.watermark; | ||
} | ||
this.writer.addPage(sectionNode.pageSize || this.pageSize, sectionNode.pageOrientation, sectionNode.pageMargins || this.pageMargins, customProperties); | ||
} | ||
this.processNode(sectionNode.section); | ||
} | ||
// columns | ||
@@ -922,2 +1003,19 @@ processColumns(columnNode) { | ||
} | ||
function findMaxFitLength(text, maxWidth, measureFn) { | ||
let low = 1; | ||
let high = text.length; | ||
let bestFit = 1; | ||
while (low <= high) { | ||
const mid = Math.floor((low + high) / 2); | ||
const part = text.substring(0, mid); | ||
const width = measureFn(part); | ||
if (width <= maxWidth) { | ||
bestFit = mid; | ||
low = mid + 1; | ||
} else { | ||
high = mid - 1; | ||
} | ||
} | ||
return bestFit; | ||
} | ||
if (!textNode._inlines || textNode._inlines.length === 0) { | ||
@@ -934,7 +1032,3 @@ return null; | ||
if (!inline.noWrap && inline.text.length > 1 && inline.width > line.getAvailableWidth()) { | ||
let widthPerChar = inline.width / inline.text.length; | ||
let maxChars = Math.floor(line.getAvailableWidth() / widthPerChar); | ||
if (maxChars < 1) { | ||
maxChars = 1; | ||
} | ||
let maxChars = findMaxFitLength(inline.text, line.getAvailableWidth(), txt => textInlines.widthOfText(txt, inline)); | ||
if (maxChars < inline.text.length) { | ||
@@ -941,0 +1035,0 @@ let newInline = cloneInline(inline); |
@@ -76,6 +76,6 @@ "use strict"; | ||
} | ||
addPage(pageSize, pageOrientation, pageMargin) { | ||
addPage(pageSize, pageOrientation, pageMargin, customProperties = {}) { | ||
let prevPage = this.page; | ||
let prevY = this.y; | ||
this.context().addPage((0, _PageSize.normalizePageSize)(pageSize, pageOrientation), (0, _PageSize.normalizePageMargin)(pageMargin)); | ||
this.context().addPage((0, _PageSize.normalizePageSize)(pageSize, pageOrientation), (0, _PageSize.normalizePageMargin)(pageMargin), customProperties); | ||
this.emit('pageChanged', { | ||
@@ -82,0 +82,0 @@ prevPage: prevPage, |
@@ -106,3 +106,5 @@ "use strict"; | ||
let pageHeight = calculatePageHeight(pages, docDefinition.pageMargins); | ||
this.pdfKitDoc.options.size = [pageSize.width, pageHeight]; | ||
pages.forEach(page => { | ||
page.pageSize.height = pageHeight; | ||
}); | ||
} | ||
@@ -109,0 +111,0 @@ const renderer = new _Renderer.default(this.pdfKitDoc, options.progressCallback); |
@@ -67,2 +67,6 @@ "use strict"; | ||
} | ||
if (typeof item.section !== 'undefined') { | ||
// section node not support style overrides | ||
return 0; | ||
} | ||
let styleNames = []; | ||
@@ -69,0 +73,0 @@ if (item.style) { |
{ | ||
"name": "pdfmake", | ||
"version": "0.3.0-beta.17", | ||
"version": "0.3.0-beta.18", | ||
"description": "Client/server side PDF printing in pure JavaScript", | ||
@@ -13,11 +13,11 @@ "main": "js/index.js", | ||
"linebreak": "^1.1.0", | ||
"pdfkit": "^0.17.0", | ||
"xmldoc": "^2.0.0" | ||
"pdfkit": "^0.17.1", | ||
"xmldoc": "^2.0.1" | ||
}, | ||
"devDependencies": { | ||
"@babel/cli": "^7.27.0", | ||
"@babel/core": "^7.26.10", | ||
"@babel/plugin-transform-modules-commonjs": "^7.26.3", | ||
"@babel/preset-env": "^7.26.9", | ||
"@eslint/js": "^9.25.1", | ||
"@babel/cli": "^7.27.2", | ||
"@babel/core": "^7.27.1", | ||
"@babel/plugin-transform-modules-commonjs": "^7.27.1", | ||
"@babel/preset-env": "^7.27.2", | ||
"@eslint/js": "^9.26.0", | ||
"assert": "^2.1.0", | ||
@@ -28,9 +28,9 @@ "babel-loader": "^10.0.0", | ||
"buffer": "^6.0.3", | ||
"core-js": "^3.41.0", | ||
"eslint": "^9.25.1", | ||
"core-js": "^3.42.0", | ||
"eslint": "^9.26.0", | ||
"eslint-plugin-jsdoc": "^50.6.11", | ||
"expose-loader": "^5.0.1", | ||
"file-saver": "^2.0.5", | ||
"globals": "^16.0.0", | ||
"mocha": "^11.1.0", | ||
"globals": "^16.1.0", | ||
"mocha": "^11.2.2", | ||
"npm-run-all": "^4.1.5", | ||
@@ -48,3 +48,3 @@ "process": "^0.11.10", | ||
"util": "^0.12.5", | ||
"webpack": "^5.99.7", | ||
"webpack": "^5.99.8", | ||
"webpack-cli": "^6.0.1" | ||
@@ -51,0 +51,0 @@ }, |
@@ -45,2 +45,3 @@ # pdfmake [![Node.js CI][githubactions_img]][githubactions_url] [![GitHub][github_img]][github_url] [![npm][npm_img]][npm_url] [![Bower][bower_img]][bower_url] [![Packagist][packagist_img]][packagist_url] [![CDNJS][cdnjs_img]][cndjs_url] | ||
* margins, | ||
* document sections, | ||
* custom page breaks, | ||
@@ -47,0 +48,0 @@ * font embedding, |
@@ -37,2 +37,6 @@ import TextInlines from './TextInlines'; | ||
measureBlock(node) { | ||
return this.measureNode(node); | ||
} | ||
measureNode(node) { | ||
@@ -43,3 +47,5 @@ return this.styleStack.auto(node, () => { | ||
if (node.columns) { | ||
if (node.section) { | ||
return extendMargins(this.measureSection(node)); | ||
} else if (node.columns) { | ||
return extendMargins(this.measureColumns(node)); | ||
@@ -470,2 +476,10 @@ } else if (node.stack) { | ||
measureSection(node) { | ||
// TODO: properties | ||
node.section = this.measureNode(node.section); | ||
return node; | ||
} | ||
measureColumns(node) { | ||
@@ -472,0 +486,0 @@ let columns = node.columns; |
@@ -23,6 +23,13 @@ import { isString, isNumber, isValue, isEmptyObject } from './helpers/variableType'; | ||
this.nodeReferences = []; | ||
return this.preprocessNode(docStructure); | ||
return this.preprocessNode(docStructure, true); | ||
} | ||
preprocessNode(node) { | ||
preprocessBlock(node) { | ||
this.parentNode = null; | ||
this.tocs = []; | ||
this.nodeReferences = []; | ||
return this.preprocessNode(node); | ||
} | ||
preprocessNode(node, isSectionAllowed = false) { | ||
// expand shortcuts and casting values | ||
@@ -37,6 +44,12 @@ if (Array.isArray(node)) { | ||
if (node.columns) { | ||
if (node.section) { | ||
if (!isSectionAllowed) { | ||
throw new Error(`Incorrect document structure, section node is only allowed at the root level of document structure: ${stringifyNode(node)}`); | ||
} | ||
return this.preprocessSection(node); | ||
} else if (node.columns) { | ||
return this.preprocessColumns(node); | ||
} else if (node.stack) { | ||
return this.preprocessVerticalContainer(node); | ||
return this.preprocessVerticalContainer(node, isSectionAllowed); | ||
} else if (node.ul) { | ||
@@ -69,2 +82,8 @@ return this.preprocessList(node); | ||
preprocessSection(node) { | ||
node.section = this.preprocessNode(node.section); | ||
return node; | ||
} | ||
preprocessColumns(node) { | ||
@@ -80,7 +99,7 @@ let columns = node.columns; | ||
preprocessVerticalContainer(node) { | ||
preprocessVerticalContainer(node, isSectionAllowed) { | ||
let items = node.stack; | ||
for (let i = 0, l = items.length; i < l; i++) { | ||
items[i] = this.preprocessNode(items[i]); | ||
items[i] = this.preprocessNode(items[i], isSectionAllowed); | ||
} | ||
@@ -87,0 +106,0 @@ |
@@ -225,3 +225,3 @@ import { isString } from './helpers/variableType'; | ||
let pageSize = getPageSize(this.getCurrentPage(), pageOrientation); | ||
this.addPage(pageSize); | ||
this.addPage(pageSize, null, this.getCurrentPage().customProperties); | ||
@@ -244,3 +244,3 @@ if (currentPageOrientation === pageSize.orientation) { | ||
addPage(pageSize, pageMargin = null) { | ||
addPage(pageSize, pageMargin = null, customProperties = {}) { | ||
if (pageMargin !== null) { | ||
@@ -252,3 +252,3 @@ this.pageMargins = pageMargin; | ||
let page = { items: [], pageSize: pageSize, pageMargins: this.pageMargins }; | ||
let page = { items: [], pageSize: pageSize, pageMargins: this.pageMargins, customProperties: customProperties }; | ||
this.pages.push(page); | ||
@@ -259,3 +259,3 @@ this.backgroundLength.push(0); | ||
this.emit('pageAdded'); | ||
this.emit('pageAdded', page); | ||
@@ -262,0 +262,0 @@ return page; |
@@ -10,3 +10,3 @@ import DocPreprocessor from './DocPreprocessor'; | ||
import { stringifyNode, getNodeId } from './helpers/node'; | ||
import { pack, offsetVector } from './helpers/tools'; | ||
import { pack, offsetVector, convertToDynamicContent } from './helpers/tools'; | ||
import TextInlines from './TextInlines'; | ||
@@ -172,2 +172,12 @@ import StyleContextStack from './StyleContextStack'; | ||
const isNecessaryAddFirstPage = (docStructure) => { | ||
if (docStructure.stack && docStructure.stack.length > 0 && docStructure.stack[0].section) { | ||
return false; | ||
} else if (docStructure.section) { | ||
return false; | ||
} | ||
return true; | ||
}; | ||
this.linearNodeList = []; | ||
@@ -179,17 +189,22 @@ docStructure = this.docPreprocessor.preprocessDocument(docStructure); | ||
this.writer.context().addListener('pageAdded', () => { | ||
this.addBackground(background); | ||
this.writer.context().addListener('pageAdded', (page) => { | ||
let backgroundGetter = background; | ||
if (page.customProperties['background'] || page.customProperties['background'] === null) { | ||
backgroundGetter = page.customProperties['background']; | ||
} | ||
this.addBackground(backgroundGetter); | ||
}); | ||
this.writer.addPage( | ||
this.pageSize, | ||
null, | ||
this.pageMargins | ||
); | ||
if (isNecessaryAddFirstPage(docStructure)) { | ||
this.writer.addPage( | ||
this.pageSize, | ||
null, | ||
this.pageMargins | ||
); | ||
} | ||
this.processNode(docStructure); | ||
this.addHeadersAndFooters(header, footer); | ||
if (watermark != null) { | ||
this.addWatermark(watermark, pdfDocument, defaultStyle); | ||
} | ||
this.addWatermark(watermark, pdfDocument, defaultStyle); | ||
@@ -209,4 +224,4 @@ return { pages: this.writer.context().pages, linearNodeList: this.linearNodeList }; | ||
this.writer.beginUnbreakableBlock(pageSize.width, pageSize.height); | ||
pageBackground = this.docPreprocessor.preprocessDocument(pageBackground); | ||
this.processNode(this.docMeasure.measureDocument(pageBackground)); | ||
pageBackground = this.docPreprocessor.preprocessBlock(pageBackground); | ||
this.processNode(this.docMeasure.measureBlock(pageBackground)); | ||
this.writer.commitUnbreakableBlock(0, 0); | ||
@@ -217,3 +232,3 @@ context.backgroundLength[context.page] += pageBackground.positions.length; | ||
addDynamicRepeatable(nodeGetter, sizeFunction) { | ||
addDynamicRepeatable(nodeGetter, sizeFunction, customPropertyName) { | ||
let pages = this.writer.context().pages; | ||
@@ -224,9 +239,20 @@ | ||
let node = nodeGetter(pageIndex + 1, l, this.writer.context().pages[pageIndex].pageSize); | ||
let customProperties = this.writer.context().getCurrentPage().customProperties; | ||
let pageNodeGetter = nodeGetter; | ||
if (customProperties[customPropertyName] || customProperties[customPropertyName] === null) { | ||
pageNodeGetter = customProperties[customPropertyName]; | ||
} | ||
if ((typeof pageNodeGetter === 'undefined') || (pageNodeGetter === null)) { | ||
continue; | ||
} | ||
let node = pageNodeGetter(pageIndex + 1, l, this.writer.context().pages[pageIndex].pageSize); | ||
if (node) { | ||
let sizes = sizeFunction(this.writer.context().getCurrentPage().pageSize, this.writer.context().getCurrentPage().pageMargins); | ||
this.writer.beginUnbreakableBlock(sizes.width, sizes.height); | ||
node = this.docPreprocessor.preprocessDocument(node); | ||
this.processNode(this.docMeasure.measureDocument(node)); | ||
node = this.docPreprocessor.preprocessBlock(node); | ||
this.processNode(this.docMeasure.measureBlock(node)); | ||
this.writer.commitUnbreakableBlock(sizes.x, sizes.y); | ||
@@ -252,23 +278,27 @@ } | ||
if (header) { | ||
this.addDynamicRepeatable(header, headerSizeFct); | ||
} | ||
if (footer) { | ||
this.addDynamicRepeatable(footer, footerSizeFct); | ||
} | ||
this.addDynamicRepeatable(header, headerSizeFct, 'header'); | ||
this.addDynamicRepeatable(footer, footerSizeFct, 'footer'); | ||
} | ||
addWatermark(watermark, pdfDocument, defaultStyle) { | ||
if (isString(watermark)) { | ||
watermark = { 'text': watermark }; | ||
} | ||
let pages = this.writer.context().pages; | ||
for (let i = 0, l = pages.length; i < l; i++) { | ||
let pageWatermark = watermark; | ||
if (pages[i].customProperties['watermark'] || pages[i].customProperties['watermark'] === null) { | ||
pageWatermark = pages[i].customProperties['watermark']; | ||
} | ||
if (!watermark.text) { // empty watermark text | ||
return; | ||
} | ||
if (pageWatermark === undefined || pageWatermark === null) { | ||
continue; | ||
} | ||
let pages = this.writer.context().pages; | ||
for (let i = 0, l = pages.length; i < l; i++) { | ||
pages[i].watermark = getWatermarkObject({ ...watermark }, pages[i].pageSize, pdfDocument, defaultStyle); | ||
if (isString(pageWatermark)) { | ||
pageWatermark = { 'text': pageWatermark }; | ||
} | ||
if (!pageWatermark.text) { // empty watermark text | ||
continue; | ||
} | ||
pages[i].watermark = getWatermarkObject({ ...pageWatermark }, pages[i].pageSize, pdfDocument, defaultStyle); | ||
} | ||
@@ -463,2 +493,4 @@ | ||
this.processVerticalContainer(node); | ||
} else if (node.section) { | ||
this.processSection(node); | ||
} else if (node.columns) { | ||
@@ -510,2 +542,71 @@ this.processColumns(node); | ||
// section | ||
processSection(sectionNode) { | ||
// TODO: properties | ||
let page = this.writer.context().getCurrentPage(); | ||
if (!page || (page && page.items.length)) { // move to new empty page | ||
// page definition inherit from current page | ||
if (sectionNode.pageSize === 'inherit') { | ||
sectionNode.pageSize = page ? { width: page.pageSize.width, height: page.pageSize.height } : undefined; | ||
} | ||
if (sectionNode.pageOrientation === 'inherit') { | ||
sectionNode.pageOrientation = page ? page.pageSize.orientation : undefined; | ||
} | ||
if (sectionNode.pageMargins === 'inherit') { | ||
sectionNode.pageMargins = page ? page.pageMargins : undefined; | ||
} | ||
if (sectionNode.header === 'inherit') { | ||
sectionNode.header = page ? page.customProperties.header : undefined; | ||
} | ||
if (sectionNode.footer === 'inherit') { | ||
sectionNode.footer = page ? page.customProperties.footer : undefined; | ||
} | ||
if (sectionNode.background === 'inherit') { | ||
sectionNode.background = page ? page.customProperties.background : undefined; | ||
} | ||
if (sectionNode.watermark === 'inherit') { | ||
sectionNode.watermark = page ? page.customProperties.watermark : undefined; | ||
} | ||
if (sectionNode.header && typeof sectionNode.header !== 'function' && sectionNode.header !== null) { | ||
sectionNode.header = convertToDynamicContent(sectionNode.header); | ||
} | ||
if (sectionNode.footer && typeof sectionNode.footer !== 'function' && sectionNode.footer !== null) { | ||
sectionNode.footer = convertToDynamicContent(sectionNode.footer); | ||
} | ||
let customProperties = {}; | ||
if (typeof sectionNode.header !== 'undefined') { | ||
customProperties.header = sectionNode.header; | ||
} | ||
if (typeof sectionNode.footer !== 'undefined') { | ||
customProperties.footer = sectionNode.footer; | ||
} | ||
if (typeof sectionNode.background !== 'undefined') { | ||
customProperties.background = sectionNode.background; | ||
} | ||
if (typeof sectionNode.watermark !== 'undefined') { | ||
customProperties.watermark = sectionNode.watermark; | ||
} | ||
this.writer.addPage( | ||
sectionNode.pageSize || this.pageSize, | ||
sectionNode.pageOrientation, | ||
sectionNode.pageMargins || this.pageMargins, | ||
customProperties | ||
); | ||
} | ||
this.processNode(sectionNode.section); | ||
} | ||
// columns | ||
@@ -1031,2 +1132,23 @@ processColumns(columnNode) { | ||
function findMaxFitLength(text, maxWidth, measureFn) { | ||
let low = 1; | ||
let high = text.length; | ||
let bestFit = 1; | ||
while (low <= high) { | ||
const mid = Math.floor((low + high) / 2); | ||
const part = text.substring(0, mid); | ||
const width = measureFn(part); | ||
if (width <= maxWidth) { | ||
bestFit = mid; | ||
low = mid + 1; | ||
} else { | ||
high = mid - 1; | ||
} | ||
} | ||
return bestFit; | ||
} | ||
if (!textNode._inlines || textNode._inlines.length === 0) { | ||
@@ -1047,7 +1169,5 @@ return null; | ||
if (!inline.noWrap && inline.text.length > 1 && inline.width > line.getAvailableWidth()) { | ||
let widthPerChar = inline.width / inline.text.length; | ||
let maxChars = Math.floor(line.getAvailableWidth() / widthPerChar); | ||
if (maxChars < 1) { | ||
maxChars = 1; | ||
} | ||
let maxChars = findMaxFitLength(inline.text, line.getAvailableWidth(), (txt) => | ||
textInlines.widthOfText(txt, inline) | ||
); | ||
if (maxChars < inline.text.length) { | ||
@@ -1054,0 +1174,0 @@ let newInline = cloneInline(inline); |
@@ -86,7 +86,7 @@ import ElementWriter from './ElementWriter'; | ||
addPage(pageSize, pageOrientation, pageMargin) { | ||
addPage(pageSize, pageOrientation, pageMargin, customProperties = {}) { | ||
let prevPage = this.page; | ||
let prevY = this.y; | ||
this.context().addPage(normalizePageSize(pageSize, pageOrientation), normalizePageMargin(pageMargin)); | ||
this.context().addPage(normalizePageSize(pageSize, pageOrientation), normalizePageMargin(pageMargin), customProperties); | ||
@@ -93,0 +93,0 @@ this.emit('pageChanged', { |
@@ -108,3 +108,5 @@ import PDFDocument from './PDFDocument'; | ||
let pageHeight = calculatePageHeight(pages, docDefinition.pageMargins); | ||
this.pdfKitDoc.options.size = [pageSize.width, pageHeight]; | ||
pages.forEach(page => { | ||
page.pageSize.height = pageHeight; | ||
}); | ||
} | ||
@@ -111,0 +113,0 @@ |
@@ -68,2 +68,6 @@ import { isString, isValue } from './helpers/variableType'; | ||
if (typeof item.section !== 'undefined') { // section node not support style overrides | ||
return 0; | ||
} | ||
let styleNames = []; | ||
@@ -70,0 +74,0 @@ |
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is not supported yet
13940691
0.32%92162
0.44%87
1.16%Updated
Updated