diff --git a/.gitignore b/.gitignore index abb965fa4..f66991985 100644 --- a/.gitignore +++ b/.gitignore @@ -9,5 +9,7 @@ doc nbproject package-lock.json yarn.lock +*pnpm-lock.yaml +.vscode .idea /js diff --git a/dev-playground/public/index.html b/dev-playground/public/index.html index dbc529dee..5888b600a 100644 --- a/dev-playground/public/index.html +++ b/dev-playground/public/index.html @@ -58,10 +58,10 @@

Playground does not make too much sense when horizontal resolution is below var editor = ace.edit('editor'); setupEditor(editor); - var names = ['basics', 'styles1', 'styles2', 'styles3', 'columns', 'tables', 'lists', 'margin', 'images', 'svgs', 'attachments']; + var names = ['basics', 'styles1', 'styles2', 'styles3', 'columns', 'tables', 'lists', 'margin', 'images', 'svgs', 'attachments', 'acroforms']; var i = 0; - ['basics', 'named-styles', 'inline-styling', 'style-overrides', 'columns', 'tables', 'lists', 'margins', 'images', 'svgs', 'attachments'].forEach(function (example) { + ['basics', 'named-styles', 'inline-styling', 'style-overrides', 'columns', 'tables', 'lists', 'margins', 'images', 'svgs', 'attachments', 'acroforms'].forEach(function (example) { $scope.examples.push({ name: names[i++], activate: function () { diff --git a/dev-playground/public/samples/acroforms b/dev-playground/public/samples/acroforms new file mode 100644 index 000000000..49411e349 --- /dev/null +++ b/dev-playground/public/samples/acroforms @@ -0,0 +1,347 @@ +{ + "subsetFonts": false, + "content": [ + { + "text": "Acroforms", + "style": "header" + }, + { + "text": [ + "It is recommended that you test your PDF form ", + "documents across all platforms and viewers that you wish to ", + "support. Refer to ", + "https://pdfkit.org/docs/forms or the PDF ", + "reference for form options and advanced form field use.\n\n" + ], + "style": "description" + }, + { + "text": "Components\n", + "style": "subHeader" + }, + { + "text": [ + "Make sure you set the subsetFonts flag to false when using ", + "form fields with text.\n\n" + ], + "style": { + "bold": true + } + }, + { + "text": "Text field", + "style": "formHeader" + }, + { + "columns": [ + [ + { + "acroform": { + "type": "text", + "id": "text_placeholder", + "options": { + "value": "Placeholder ..." + } + }, + "style": "textFieldStyle", + "height": 15, + "italics": true + }, + { + "acroform": { + "type": "text", + "id": "text_date", + "options": { + "format": { + "type": "date" + }, + "align": "center", + "value": "10/12" + } + }, + "style": "textFieldStyle", + "height": 15 + }, + { + "acroform": { + "type": "text", + "id": "text_multi", + "options": { + "multiline": true, + "value": "multiline text form " + } + }, + "style": "textFieldStyle", + "height": 50 + } + ], + [ + { + "acroform": { + "type": "text", + "id": "text_alignment", + "options": { + "align": "right", + "value": "right alignment" + } + }, + "style": "textFieldStyle", + "height": 15 + }, + { + "acroform": { + "type": "text", + "id": "text_color", + "options": { + "align": "center", + "required": true, + "value": "Ω©®℅¥123" + } + }, + "style": "textFieldStyle", + "height": 15 + } + ], + [ + { + "acroform": { + "type": "text", + "id": "text_currency", + "options": { + "align": "right", + "format": { + "type": "number", + "nDec": 2, + "sepComma": true, + "negStyle": "ParensRed", + "currency": "$", + "currencyPrepend": true + }, + "value": "$123,346.99" + } + }, + "style": "textFieldStyle", + "height": 15 + }, + { + "acroform": { + "type": "text", + "id": "text_backgroundcolor", + "options": { + "backgroundColor": "yellow", + "borderColor": "green", + "align": "center", + "value": "background color" + } + }, + "style": "textFieldStyle", + "height": 15 + } + ] + ] + }, + { + "columns": [ + [ + { + "text": "\nList", + "style": "formHeader" + }, + { + "acroform": { + "type": "list", + "id": "list1", + "options": { + "select": [ + "", + "A", + "B", + "C" + ] + } + }, + "width": 100, + "height": 60 + } + ], + [ + { + "text": "\nCombobox", + "style": "formHeader" + }, + { + "acroform": { + "type": "combo", + "id": "combo1", + "options": { + "select": [ + "", + "A", + "B", + "C" + ], + "defaultValue": "" + } + }, + "width": 100, + "height": 20 + } + ], + [ + { + "text": "\nCheckbox form", + "style": "formHeader" + }, + { + "acroform": { + "type": "checkbox", + "id": "checkbox1", + "options": { + "selected": false + } + }, + "width": 20, + "height": 20 + } + ] + ] + }, + { + "text": "\nYou can also use forms inline with text\n\n", + "style": "subHeader" + }, + { + "text": [ + "Check this box! ", + { + "acroform": { + "type": "checkbox", + "id": "checkbox2", + "options": { + "selected": false + } + }, + "width": 15, + "height": 15 + }, + "\n\n" + ], + "alignment": "center" + }, + { + "text": [ + "The weather was very ", + { + "acroform": { + "type": "combo", + "id": "combo_story1", + "options": { + "select": [ + "", + "nice", + "bad" + ], + "defaultValue": "" + } + }, + "width": 50, + "height": 9.5 + }, + " and the skies were ", + { + "acroform": { + "type": "combo", + "id": "combo_story2", + "options": { + "select": [ + "", + "clear", + "cloudy" + ], + "defaultValue": "" + } + }, + "width": 50, + "height": 9.5 + }, + ". A fox named ", + { + "acroform": { + "type": "text", + "id": "text_story1" + }, + "width": 50, + "height": 9.5 + }, + " and friends were playing a game at the park, when suddenly", + "... ", + { + "text": "finish the story", + "style": { + "italics": true, + "bold": true + } + } + ] + }, + { + "acroform": { + "type": "text", + "id": "text_story2", + "options": { + "multiline": true + } + }, + "style": "textFieldStyle", + "width": "*", + "height": 100 + } + ], + "styles": { + "header": { + "fontSize": 18, + "bold": true, + "margin": [ + 0, + 0, + 0, + 10 + ], + "lineHeight": 0.3 + }, + "description": { + "fontSize": 13, + "margin": [ + 0, + 10, + 0, + 5 + ] + }, + "subHeader": { + "bold": true, + "fontSize": 13 + }, + "formHeader": { + "fontSize": 12, + "color": "black" + }, + "tableCell": { + "margin": [ + 0, + 5, + 0, + 5 + ] + }, + "textFieldStyle": { + "font": "Helvetica", + "margin": [ + 0, + 0, + 5, + 5 + ] + } + } +} \ No newline at end of file diff --git a/dev-playground/server.js b/dev-playground/server.js index 0a3dbea6b..4bbb392ba 100644 --- a/dev-playground/server.js +++ b/dev-playground/server.js @@ -19,7 +19,13 @@ function createPdfBinary(docDefinition) { bold: path.join(__dirname, '..', 'examples', '/fonts/Roboto-Medium.ttf'), italics: path.join(__dirname, '..', 'examples', '/fonts/Roboto-Italic.ttf'), bolditalics: path.join(__dirname, '..', 'examples', '/fonts/Roboto-MediumItalic.ttf') - } + }, + Helvetica: { + normal: 'Helvetica', + bold: 'Helvetica-Bold', + italics: 'Helvetica-Oblique', + bolditalics: 'Helvetica-BoldOblique' + }, }; pdfmake.setFonts(fonts); @@ -35,6 +41,7 @@ app.post('/pdf', function (req, res) { res.contentType('application/pdf'); res.send(binary); }, function (error) { + console.log(error); //print in console res.send('ERROR:' + error); }); diff --git a/package.json b/package.json index ef1164235..1e6027304 100644 --- a/package.json +++ b/package.json @@ -31,6 +31,7 @@ "file-saver": "^2.0.5", "globals": "^15.14.0", "mocha": "^11.0.1", + "nodemon": "^3.1.9", "npm-run-all": "^4.1.5", "process": "^0.11.10", "rewire": "^7.0.0", @@ -62,7 +63,8 @@ "build:fonts": "shx mkdir -p build/fonts && shx mkdir -p build/fonts/Roboto && shx cp -r fonts/Roboto/*.* build/fonts/Roboto && brfs \"./src/browser-extensions/fonts/Roboto.js\" > build/fonts/Roboto.js", "lint": "eslint \"./src/**/*.js\" \"./tests/**/*.js\" \"./examples/**/*.js\" \"./standard-fonts/**/*.js\" \"./fonts/**/*.js\"", "mocha": "mocha --reporter spec \"./tests/**/*.spec.js\"", - "playground": "node dev-playground/server.js" + "playground": "node dev-playground/server.js", + "playground:watch": "nodemon dev-playground/server.js" }, "repository": { "type": "git", diff --git a/src/DocMeasure.js b/src/DocMeasure.js index 79eeebbcf..c184b8b59 100644 --- a/src/DocMeasure.js +++ b/src/DocMeasure.js @@ -38,7 +38,6 @@ class DocMeasure { return this.styleStack.auto(node, () => { // TODO: refactor + rethink whether this is the proper way to handle margins node._margin = getNodeMargin(node, this.styleStack); - if (node.columns) { return extendMargins(this.measureColumns(node)); } else if (node.stack) { @@ -63,6 +62,8 @@ class DocMeasure { return extendMargins(this.measureQr(node)); } else if (node.attachment) { return extendMargins(this.measureAttachment(node)); + } else if (node.acroform) { + return extendMargins(this.measureAcroForm(node)); } else { throw new Error(`Unrecognized document structure: ${stringifyNode(node)}`); } @@ -708,6 +709,23 @@ class DocMeasure { return node; } + + measureAcroForm(node) { + node._minWidth = 10; + node._minHeight = 10; + + let font = StyleContextStack.getStyleProperty(node, this.styleStack, 'font', 'Roboto'); + let bold = StyleContextStack.getStyleProperty(node, this.styleStack, 'bold', false); + let italics = StyleContextStack.getStyleProperty(node, this.styleStack, 'italics', false); + + node.font = font; + node.bold = bold; + node.italics = italics; + + node.alignment = StyleContextStack.getStyleProperty(node, this.styleStack, 'alignment', 'left'); + + return node; + } } export default DocMeasure; diff --git a/src/DocPreprocessor.js b/src/DocPreprocessor.js index 6002555b3..bb44bf534 100644 --- a/src/DocPreprocessor.js +++ b/src/DocPreprocessor.js @@ -59,11 +59,17 @@ class DocPreprocessor { return this.preprocessAttachment(node); } else if (node.pageReference || node.textReference) { return this.preprocessText(node); + } else if (node.acroform) { + return this.preprocessAcroForm(node); } else { throw new Error(`Unrecognized document structure: ${stringifyNode(node)}`); } } + preprocessAcroForm(node) { + return node; + } + preprocessColumns(node) { let columns = node.columns; diff --git a/src/ElementWriter.js b/src/ElementWriter.js index fdf7d6ed1..b3bb92038 100644 --- a/src/ElementWriter.js +++ b/src/ElementWriter.js @@ -203,6 +203,33 @@ class ElementWriter extends EventEmitter { return position; } + addAcroForm(node, index) { + let context = this.context(); + let page = context.getCurrentPage(); + let position = this.getCurrentPositionOnPage(); + + if (!page) { + return false; + } + + if (node._x === undefined) { + node._x = node.x || 0; + } + + addPageItem(page, { + type: 'acroform', + item: node + }, index); + + node.x = context.x + node._x; + node.y = context.y; + + + context.moveDown(node.height || node._minHeight); + + return position; + } + addAttachment(attachment, index) { let context = this.context(); let page = context.getCurrentPage(); diff --git a/src/LayoutBuilder.js b/src/LayoutBuilder.js index 1dc884a28..7ef979b83 100644 --- a/src/LayoutBuilder.js +++ b/src/LayoutBuilder.js @@ -7,7 +7,7 @@ import TableProcessor from './TableProcessor'; import Line from './Line'; import { isString, isValue, isNumber } from './helpers/variableType'; import { stringifyNode, getNodeId } from './helpers/node'; -import { pack, offsetVector } from './helpers/tools'; +import { offsetVector } from './helpers/tools'; import TextInlines from './TextInlines'; import StyleContextStack from './StyleContextStack'; @@ -36,7 +36,7 @@ class LayoutBuilder { } registerTableLayouts(tableLayouts) { - this.tableLayouts = pack(this.tableLayouts, tableLayouts); + this.tableLayouts = { ...this.tableLayouts, ...tableLayouts };// pack(this.tableLayouts, tableLayouts); } /** @@ -78,7 +78,7 @@ class LayoutBuilder { let nodeInfo = {}; [ 'id', 'text', 'ul', 'ol', 'table', 'image', 'qr', 'canvas', 'svg', 'columns', - 'headlineLevel', 'style', 'pageBreak', 'pageOrientation', + 'headlineLevel', 'style', 'pageBreak', 'pageOrientation', 'acroForm', 'type', 'options', 'width', 'height' ].forEach(key => { if (node[key] !== undefined) { @@ -475,6 +475,8 @@ class LayoutBuilder { this.processQr(node); } else if (node.attachment) { this.processAttachment(node); + } else if (node.acroform) { + this.processAcroForm(node); } else if (!node._span) { throw new Error(`Unrecognized document structure: ${stringifyNode(node)}`); } @@ -954,7 +956,7 @@ class LayoutBuilder { } } - // leafs (texts) + // leafs (texts, acroform)) processLeaf(node) { let line = this.buildNextLine(node); if (line && (node.tocItem || node.id)) { @@ -1033,7 +1035,7 @@ class LayoutBuilder { let inline = textNode._inlines.shift(); isForceContinue = false; - if (!inline.noWrap && inline.text.length > 1 && inline.width > line.getAvailableWidth()) { + if (!inline.noWrap && inline.text && 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) { @@ -1084,6 +1086,13 @@ class LayoutBuilder { node.positions.push(position); } + processAcroForm (node) { + let availableWidth = this.writer.context().availableWidth; + let position = this.writer.addAcroForm(node); + node.positions.push(position); + node.availableWidth = availableWidth; + } + processAttachment(node) { let position = this.writer.addAttachment(node); node.positions.push(position); diff --git a/src/Line.js b/src/Line.js index 7ff24511f..293dc28b1 100644 --- a/src/Line.js +++ b/src/Line.js @@ -33,13 +33,7 @@ class Line { * @returns {number} */ getHeight() { - let max = 0; - - this.inlines.forEach(item => { - max = Math.max(max, item.height || 0); - }); - - return max; + return Math.max(...this.inlines.map(item => item.height || 0)); } /** @@ -49,7 +43,7 @@ class Line { let y = 0; this.inlines.forEach(inline => { - y = Math.max(y, inline.font.ascender / 1000 * inline.fontSize); + y = Math.max(y, inline.acroform ? inline.height : inline.font.ascender / 1000 * inline.fontSize); }); return y; diff --git a/src/PDFDocument.js b/src/PDFDocument.js index 90781199d..0c873d542 100644 --- a/src/PDFDocument.js +++ b/src/PDFDocument.js @@ -13,7 +13,7 @@ const typeName = (bold, italics) => { }; class PDFDocument extends PDFKit { - constructor(fonts = {}, images = {}, patterns = {}, attachments = {}, options = {}, virtualfs = null) { + constructor(fonts = {}, images = {}, patterns = {}, attachments = {}, options = {}, virtualfs = null, subsetFonts = true) { super(options); this.fonts = {}; @@ -43,6 +43,7 @@ class PDFDocument extends PDFKit { this.images = images; this.attachments = attachments; this.virtualfs = virtualfs; + this.subsetFonts = subsetFonts; //TODO maybe automatically set this flag } getFontType(bold, italics) { @@ -76,7 +77,9 @@ class PDFDocument extends PDFKit { def[0] = this.virtualfs.readFileSync(def[0]); } + this.fontCache[familyName][type] = this.font(...def)._font; + } return this.fontCache[familyName][type]; @@ -171,4 +174,5 @@ class PDFDocument extends PDFKit { } } + export default PDFDocument; diff --git a/src/PageElementWriter.js b/src/PageElementWriter.js index 97fc2047c..af331e788 100644 --- a/src/PageElementWriter.js +++ b/src/PageElementWriter.js @@ -45,6 +45,10 @@ class PageElementWriter extends ElementWriter { return this._fitOnPage(() => super.addAttachment(attachment, index)); } + addAcroForm(node, index) { + return this._fitOnPage(() => super.addAcroForm(node, index)); + } + addVector(vector, ignoreContextX, ignoreContextY, index, forcePage) { return super.addVector(vector, ignoreContextX, ignoreContextY, index, forcePage); } diff --git a/src/Printer.js b/src/Printer.js index ca3798960..2a3192d90 100644 --- a/src/Printer.js +++ b/src/Printer.js @@ -85,7 +85,7 @@ class PdfPrinter { font: null }; - this.pdfKitDoc = new PDFDocument(this.fontDescriptors, docDefinition.images, docDefinition.patterns, docDefinition.attachments, pdfOptions, this.virtualfs); + this.pdfKitDoc = new PDFDocument(this.fontDescriptors, docDefinition.images, docDefinition.patterns, docDefinition.attachments, pdfOptions, this.virtualfs, docDefinition.subsetFonts); embedFiles(docDefinition, this.pdfKitDoc); const builder = new LayoutBuilder(pageSize, normalizePageMargin(docDefinition.pageMargins), new SVGMeasure()); diff --git a/src/Renderer.js b/src/Renderer.js index 9c1f323c7..d3b00c1c7 100644 --- a/src/Renderer.js +++ b/src/Renderer.js @@ -41,6 +41,7 @@ class Renderer { constructor(pdfDocument, progressCallback) { this.pdfDocument = pdfDocument; this.progressCallback = progressCallback; + this.hasFormInit = false; } renderPages(pages) { @@ -74,6 +75,9 @@ class Renderer { case 'svg': this.renderSVG(item.item); break; + case 'acroform': + this.renderAcroForm(item.item); + break; case 'attachment': this.renderAttachment(item.item); break; @@ -143,43 +147,52 @@ class Renderer { let inline = line.inlines[i]; let shiftToBaseline = lineHeight - ((inline.font.ascender / 1000) * inline.fontSize) - descent; - if (inline._pageNodeRef) { - preparePageNodeRefLine(inline._pageNodeRef, inline); - } + if (inline.acroform) { + //TODO positioning issue + let shiftedY = y + (lineHeight - ((inline.font.ascender / 1000) * inline.height) - descent); + inline.y = shiftedY; + inline.x = x + inline.x; - let options = { - lineBreak: false, - textWidth: inline.width, - characterSpacing: inline.characterSpacing, - wordCount: 1, - link: inline.link - }; + this.renderAcroForm(inline); + } else { + if (inline._pageNodeRef) { + preparePageNodeRefLine(inline._pageNodeRef, inline); + } - if (inline.linkToDestination) { - options.goTo = inline.linkToDestination; - } + let options = { + lineBreak: false, + textWidth: inline.width, + characterSpacing: inline.characterSpacing, + wordCount: 1, + link: inline.link + }; - if (line.id && i === 0) { - options.destination = line.id; - } + if (inline.linkToDestination) { + options.goTo = inline.linkToDestination; + } - if (inline.fontFeatures) { - options.features = inline.fontFeatures; - } + if (line.id && i === 0) { + options.destination = line.id; + } + + if (inline.fontFeatures) { + options.features = inline.fontFeatures; + } - let opacity = isNumber(inline.opacity) ? inline.opacity : 1; - this.pdfDocument.opacity(opacity); - this.pdfDocument.fill(inline.color || 'black'); + let opacity = isNumber(inline.opacity) ? inline.opacity : 1; + this.pdfDocument.opacity(opacity); + this.pdfDocument.fill(inline.color || 'black'); - this.pdfDocument._font = inline.font; - this.pdfDocument.fontSize(inline.fontSize); + this.pdfDocument._font = inline.font; + this.pdfDocument.fontSize(inline.fontSize); - let shiftedY = offsetText(y + shiftToBaseline, inline); - this.pdfDocument.text(inline.text, x + inline.x, shiftedY, options); + let shiftedY = offsetText(y + shiftToBaseline, inline); + this.pdfDocument.text(inline.text, x + inline.x, shiftedY, options); - if (inline.linkToPage) { - this.pdfDocument.ref({ Type: 'Action', S: 'GoTo', D: [inline.linkToPage, 0, 0] }).end(); - this.pdfDocument.annotate(x + inline.x, shiftedY, inline.width, inline.height, { Subtype: 'Link', Dest: [inline.linkToPage - 1, 'XYZ', null, null, null] }); + if (inline.linkToPage) { + this.pdfDocument.ref({ Type: 'Action', S: 'GoTo', D: [inline.linkToPage, 0, 0] }).end(); + this.pdfDocument.annotate(x + inline.x, shiftedY, inline.width, inline.height, { Subtype: 'Link', Dest: [inline.linkToPage - 1, 'XYZ', null, null, null] }); + } } } @@ -280,6 +293,81 @@ class Renderer { } } + renderAcroForm(node) { + const { font, bold, italics } = node; + let { type, options } = node.acroform; + + if (options == null) { + options = {}; + } + + if (this.hasFormInit == false) { + this.pdfDocument.initForm(); + this.hasFormInit = true; + } + + const setFont = () => { + if (typeof font === "string") { + this.pdfDocument._font = this.pdfDocument.provideFont(font, bold, italics); + } else { + this.pdfDocument._font = font; + } + // if (this.hasFormInit) { + // this.pdfDocument.addFontToAcroFormDict(); + // } + }; + + const id = node.acroform.id; + + if (id == null) { + throw new Error(`Acroform field ${id} requires an ID`); + } + + let width = node.width || node.availableWidth || (!isNaN(node._calcWidth) && node._calcWidth) || node._minWidth; + if (node.width == '*') { + width = node.availableWidth; + } + + if (width == null) { + throw new Error(`Form ${type} width is undefined`); + } + + let resolvedType; + + setFont(); + switch (type) { + case "text": + case "formText": + resolvedType = "formText"; + break; + case "button": + case "formPushButton": + resolvedType = "formPushButton"; + break; + case "list": + case "formList": + resolvedType = "formList"; + break; + case "combo": + case "formCombo": + resolvedType = "formCombo"; + break; + case "checkbox": + case "formCheckbox": + resolvedType = "formCheckbox"; + break; + case "radio": + case "formRadio": + case "formRadioButton": + resolvedType = "formRadioButton"; + break; + default: + throw new Error(`Unrecognized acroform type: ${type}`); + } + + this.pdfDocument[resolvedType](id, node.x, node.y, width, node.height, options); + } + renderImage(image) { let opacity = isNumber(image.opacity) ? image.opacity : 1; this.pdfDocument.opacity(opacity); diff --git a/src/TextBreaker.js b/src/TextBreaker.js index 4e4aff3df..c901277be 100644 --- a/src/TextBreaker.js +++ b/src/TextBreaker.js @@ -104,16 +104,20 @@ class TextBreaker { let noWrap = StyleContextStack.getStyleProperty(item || {}, styleContextStack, 'noWrap', false); if (isObject(item)) { - if (item._textRef && item._textRef._textNodeRef.text) { - item.text = item._textRef._textNodeRef.text; + if (item.text) { + if (item._textRef && item._textRef._textNodeRef.text) { + item.text = item._textRef._textNodeRef.text; + } + words = splitWords(item.text, noWrap); + } else if (item.acroform) { + words = [item]; } - words = splitWords(item.text, noWrap); style = StyleContextStack.copyStyle(item); } else { words = splitWords(item, noWrap); } - if (lastWord && words.length) { + if (lastWord && words.length && !lastWord.acroform) { let firstWord = getFirstWord(words, noWrap); let wrapWords = splitWords(lastWord + firstWord, false); @@ -123,9 +127,14 @@ class TextBreaker { } for (let i2 = 0, l2 = words.length; i2 < l2; i2++) { - let result = { - text: words[i2].text - }; + let result = {}; + if (words[0].acroform) { + result = words[0]; + } else { + result = { + text: words[i2].text + }; + } if (words[i2].lineEnd) { result.lineEnd = true; @@ -138,7 +147,11 @@ class TextBreaker { lastWord = null; if (i + 1 < l) { - lastWord = getLastWord(words, noWrap); + if (words[0].acroform) { + lastWord = words[0]; + } else { + lastWord = getLastWord(words, noWrap); + } } } diff --git a/src/TextInlines.js b/src/TextInlines.js index 878db5a0a..713555e79 100644 --- a/src/TextInlines.js +++ b/src/TextInlines.js @@ -121,7 +121,7 @@ class TextInlines { item.link = StyleContextStack.getStyleProperty(item, styleContextStack, 'link', null); item.linkToPage = StyleContextStack.getStyleProperty(item, styleContextStack, 'linkToPage', null); item.linkToDestination = StyleContextStack.getStyleProperty(item, styleContextStack, 'linkToDestination', null); - item.noWrap = StyleContextStack.getStyleProperty(item, styleContextStack, 'noWrap', null); + item.noWrap = item.acroform ? true: StyleContextStack.getStyleProperty(item, styleContextStack, 'noWrap', null); item.opacity = StyleContextStack.getStyleProperty(item, styleContextStack, 'opacity', 1); item.sup = StyleContextStack.getStyleProperty(item, styleContextStack, 'sup', false); item.sub = StyleContextStack.getStyleProperty(item, styleContextStack, 'sub', false); @@ -133,28 +133,33 @@ class TextInlines { let lineHeight = StyleContextStack.getStyleProperty(item, styleContextStack, 'lineHeight', 1); - item.width = this.widthOfText(item.text, item); - item.height = item.font.lineHeight(item.fontSize) * lineHeight; + if (item.acroform) { + item.width = item.width || 25; + item.height = item.height || 15; + } else { + item.width = this.widthOfText(item.text, item); + item.height = item.font.lineHeight(item.fontSize) * lineHeight; - if (!item.leadingCut) { - item.leadingCut = 0; - } + if (!item.leadingCut) { + item.leadingCut = 0; + } - let preserveLeadingSpaces = StyleContextStack.getStyleProperty(item, styleContextStack, 'preserveLeadingSpaces', false); - if (!preserveLeadingSpaces) { - let leadingSpaces = item.text.match(LEADING); - if (leadingSpaces) { - item.leadingCut += this.widthOfText(leadingSpaces[0], item); + let preserveLeadingSpaces = StyleContextStack.getStyleProperty(item, styleContextStack, 'preserveLeadingSpaces', false); + if (!preserveLeadingSpaces) { + let leadingSpaces = item.text.match(LEADING); + if (leadingSpaces) { + item.leadingCut += this.widthOfText(leadingSpaces[0], item); + } } - } - item.trailingCut = 0; + item.trailingCut = 0; - let preserveTrailingSpaces = StyleContextStack.getStyleProperty(item, styleContextStack, 'preserveTrailingSpaces', false); - if (!preserveTrailingSpaces) { - let trailingSpaces = item.text.match(TRAILING); - if (trailingSpaces) { - item.trailingCut = this.widthOfText(trailingSpaces[0], item); + let preserveTrailingSpaces = StyleContextStack.getStyleProperty(item, styleContextStack, 'preserveTrailingSpaces', false); + if (!preserveTrailingSpaces) { + let trailingSpaces = item.text.match(TRAILING); + if (trailingSpaces) { + item.trailingCut = this.widthOfText(trailingSpaces[0], item); + } } } }, this);