: str_replace(): Passing null to parameter #2 ($replace) of type array|string is deprecated in
typeface: xfaFont.typeface,
posture: xfaFont.posture,
letterSpacing: xfaFont.letterSpacing
const typeface = fontFinder.find(xfaFont.typeface);
[this.pdfFont, this.xfaFont] = this.defaultFont(fontFinder);
this.pdfFont = selectFont(xfaFont, typeface);
[this.pdfFont, this.xfaFont] = this.defaultFont(fontFinder);
defaultFont(fontFinder) {
const font = fontFinder.find("Helvetica", false) || fontFinder.find("Myriad Pro", false) || fontFinder.find("Arial", false) || fontFinder.getDefault();
const pdfFont = font.regular;
const info = pdfFont.cssFontInfo;
typeface: info.fontFamily,
return [pdfFont, xfaFont];
constructor(defaultXfaFont, defaultParaMargin, defaultLineHeight, fontFinder) {
this.fontFinder = fontFinder;
this.stack = [new FontInfo(defaultXfaFont, defaultParaMargin, defaultLineHeight, fontFinder)];
pushData(xfaFont, margin, lineHeight) {
const lastFont = this.stack.at(-1);
for (const name of ["typeface", "posture", "weight", "size", "letterSpacing"]) {
xfaFont[name] = lastFont.xfaFont[name];
for (const name of ["top", "bottom", "left", "right"]) {
if (isNaN(margin[name])) {
margin[name] = lastFont.paraMargin[name];
const fontInfo = new FontInfo(xfaFont, margin, lineHeight || lastFont.lineHeight, this.fontFinder);
fontInfo.pdfFont = lastFont.pdfFont;
this.stack.push(fontInfo);
return this.stack.at(-1);
constructor(defaultXfaFont, defaultParaMargin, defaultLineHeight, fonts) {
this.fontSelector = new FontSelector(defaultXfaFont, defaultParaMargin, defaultLineHeight, fonts);
pushData(xfaFont, margin, lineHeight) {
this.fontSelector.pushData(xfaFont, margin, lineHeight);
return this.fontSelector.popFont();
const lastFont = this.fontSelector.topFont();
this.extraHeight += lastFont.paraMargin.top + lastFont.paraMargin.bottom;
const lastFont = this.fontSelector.topFont();
const fontSize = lastFont.xfaFont.size;
const letterSpacing = lastFont.xfaFont.letterSpacing;
const pdfFont = lastFont.pdfFont;
const fontLineHeight = pdfFont.lineHeight || 1.2;
const lineHeight = lastFont.lineHeight || Math.max(1.2, fontLineHeight) * fontSize;
const lineGap = pdfFont.lineGap === undefined ? 0.2 : pdfFont.lineGap;
const noGap = fontLineHeight - lineGap;
const firstLineHeight = Math.max(1, noGap) * fontSize;
const scale = fontSize / 1000;
const fallbackWidth = pdfFont.defaultWidth || pdfFont.charsToGlyphs(" ")[0].width;
for (const line of str.split(/[\u2029\n]/)) {
const encodedLine = pdfFont.encodeString(line).join("");
const glyphs = pdfFont.charsToGlyphs(encodedLine);
for (const glyph of glyphs) {
const width = glyph.width || fallbackWidth;
this.glyphs.push([width * scale + letterSpacing, lineHeight, firstLineHeight, glyph.unicode, false]);
this.glyphs.push([0, 0, 0, "\n", true]);
for (const line of str.split(/[\u2029\n]/)) {
for (const char of line.split("")) {
this.glyphs.push([fontSize, 1.2 * fontSize, fontSize, char, false]);
this.glyphs.push([0, 0, 0, "\n", true]);
for (let i = 0, ii = this.glyphs.length; i < ii; i++) {
const [glyphWidth, lineHeight, firstLineHeight, char, isEOL] = this.glyphs[i];
const isSpace = char === " ";
const glyphHeight = isFirstLine ? firstLineHeight : lineHeight;
width = Math.max(width, currentLineWidth);
height += currentLineHeight;
currentLineHeight = glyphHeight;
if (currentLineWidth + glyphWidth > maxWidth) {
width = Math.max(width, currentLineWidth);
height += currentLineHeight;
currentLineHeight = glyphHeight;
currentLineHeight = Math.max(glyphHeight, currentLineHeight);
lastSpaceWidth = currentLineWidth;
currentLineWidth += glyphWidth;
if (currentLineWidth + glyphWidth > maxWidth) {
height += currentLineHeight;
currentLineHeight = glyphHeight;
if (lastSpacePos !== -1) {
width = Math.max(width, lastSpaceWidth);
width = Math.max(width, currentLineWidth);
currentLineWidth = glyphWidth;
currentLineWidth += glyphWidth;
currentLineHeight = Math.max(glyphHeight, currentLineHeight);
width = Math.max(width, currentLineWidth);
height += currentLineHeight + this.extraHeight;
width: WIDTH_FACTOR * width,
;// CONCATENATED MODULE: ./src/core/xfa/som.js
const namePattern = /^[^.[]+/;
const indexPattern = /^[^\]]+/;
const shortcuts = new Map([["$data", (root, current) => root.datasets ? root.datasets.data : root], ["$record", (root, current) => (root.datasets ? root.datasets.data : root)[$getChildren]()[0]], ["$template", (root, current) => root.template], ["$connectionSet", (root, current) => root.connectionSet], ["$form", (root, current) => root.form], ["$layout", (root, current) => root.layout], ["$host", (root, current) => root.host], ["$dataWindow", (root, current) => root.dataWindow], ["$event", (root, current) => root.event], ["!", (root, current) => root.datasets], ["$xfa", (root, current) => root], ["xfa", (root, current) => root], ["$", (root, current) => current]]);
const somCache = new WeakMap();
function parseIndex(index) {
return parseInt(index, 10) || 0;
function parseExpression(expr, dotDotAllowed, noExpr = true) {
let match = expr.match(namePattern);
while (pos < expr.length) {
const char = expr.charAt(pos++);
match = expr.slice(pos).match(indexPattern);
warn("XFA - Invalid index in SOM expression");
parsed.at(-1).index = parseIndex(match[0]);
pos += match[0].length + 1;
switch (expr.charAt(pos)) {
operator = operators.dotDot;
operator = operators.dotHash;
warn("XFA - SOM expression contains a FormCalc subexpression which is not supported for now.");
operator = operators.dotBracket;
warn("XFA - SOM expression contains a JavaScript subexpression which is not supported for now.");
operator = operators.dotParen;
operator = operators.dot;
match = expr.slice(pos).match(namePattern);
cacheName: expr.slice(spos, pos),
function searchNode(root, container, expr, dotDotAllowed = true, useCache = true) {
const parsed = parseExpression(expr, dotDotAllowed);
const fn = shortcuts.get(parsed[0].name);
root = [fn(root, container)];
isQualified = container === null;
root = [container || root];
for (let ii = parsed.length; i < ii; i++) {
for (const node of root) {
cached = somCache.get(node);
somCache.set(node, cached);
children = cached.get(cacheName);
children = node[$getChildrenByName](name, false);
children = node[$getChildrenByName](name, true);
children = node[$getChildrenByClass](name);
children = children.isXFAObjectArray ? children.children : [children];
cached.set(cacheName, children);
if (children.length > 0) {
if (nodes.length === 0 && !isQualified && i === 0) {
const parent = container[$getParent]();
root = isFinite(index) ? nodes.filter(node => index < node.length).map(node => node[index]) : nodes.flat();
function createDataNode(root, container, expr) {
const parsed = parseExpression(expr);
if (parsed.some(x => x.operator === operators.dotDot)) {
const fn = shortcuts.get(parsed[0].name);
root = fn(root, container);
root = container || root;
for (let ii = parsed.length; i < ii; i++) {
return root.createNodes(parsed.slice(i));
children = root[$getChildrenByName](name, false);
children = root[$getChildrenByName](name, true);
children = root[$getChildrenByClass](name);
children = children.isXFAObjectArray ? children.children : [children];
if (children.length === 0) {
return root.createNodes(parsed.slice(i));
if (index < children.length) {
const child = children[index];
if (!child.isXFAObject) {
warn(`XFA - Cannot create a node.`);
parsed[i].index = index - children.length;
return root.createNodes(parsed.slice(i));
;// CONCATENATED MODULE: ./src/core/xfa/xfa_object.js
const _applyPrototype = Symbol();
const _attributes = Symbol();
const _attributeNames = Symbol();
const _children = Symbol("_children");
const _cloneAttribute = Symbol();
const _dataValue = Symbol();
const _defaultValue = Symbol();
const _filteredChildrenGenerator = Symbol();
const _getPrototype = Symbol();
const _getUnsetAttributes = Symbol();
const _hasChildren = Symbol();
const _options = Symbol();
const _parent = Symbol("parent");
const _resolvePrototypesHelper = Symbol();
const _setAttributes = Symbol();
const _validator = Symbol();
const NS_DATASETS = NamespaceIds.datasets.id;
constructor(nsId, name, hasChildren = false) {
this[$namespaceId] = nsId;
this[_hasChildren] = hasChildren;
this[$uid] = `${name}${uid++}`;
this[$globalData] = null;
for (let i = 0, ii = isFinite(index) ? index : 0; i <= ii; i++) {
const nsId = root[$namespaceId] === NS_DATASETS ? -1 : root[$namespaceId];
node = new XmlObject(nsId, name);
root[$appendChild](node);