Skip to content

Commit f5a19b0

Browse files
authored
Support for text with newlines in Acroform TextFields (#3298)
1 parent af2d39d commit f5a19b0

File tree

4 files changed

+105
-33
lines changed

4 files changed

+105
-33
lines changed

src/modules/acroform.js

+69-33
Original file line numberDiff line numberDiff line change
@@ -217,6 +217,11 @@ var calculateX = function(formObject, text) {
217217
: text;
218218
// split into array of words
219219
var textSplit = text.split(" ");
220+
if (formObject.multiline) {
221+
textSplit = textSplit.map(word => word.split("\n"));
222+
} else {
223+
textSplit = textSplit.map(word => [word]);
224+
}
220225

221226
var fontSize = maxFontSize; // The Starting fontSize (The Maximum)
222227
var lineSpacing = 2;
@@ -229,7 +234,7 @@ var calculateX = function(formObject, text) {
229234

230235
var isSmallerThanWidth = function(i, lastLine, fontSize) {
231236
if (i + 1 < textSplit.length) {
232-
var tmp = lastLine + " " + textSplit[i + 1];
237+
var tmp = lastLine + " " + textSplit[i + 1][0];
233238
var TextWidth = calculateFontSpace(tmp, formObject, fontSize).width;
234239
var FieldWidth = width - 2 * borderPadding;
235240
return TextWidth <= FieldWidth;
@@ -253,6 +258,7 @@ var calculateX = function(formObject, text) {
253258
var firstWordInLine = 0,
254259
lastWordInLine = 0;
255260
var lastLength;
261+
var currWord = 0;
256262

257263
if (fontSize <= 0) {
258264
// In case, the Text doesn't fit at all
@@ -269,51 +275,81 @@ var calculateX = function(formObject, text) {
269275

270276
var lastLine = "";
271277
var lineCount = 0;
272-
Line: for (var i in textSplit) {
278+
Line: for (var i = 0; i < textSplit.length; i++) {
273279
if (textSplit.hasOwnProperty(i)) {
274-
lastLine += textSplit[i] + " ";
275-
// Remove last blank
276-
lastLine =
277-
lastLine.substr(lastLine.length - 1) == " "
278-
? lastLine.substr(0, lastLine.length - 1)
279-
: lastLine;
280-
var key = parseInt(i);
281-
var nextLineIsSmaller = isSmallerThanWidth(key, lastLine, fontSize);
282-
var isLastWord = i >= textSplit.length - 1;
283-
if (nextLineIsSmaller && !isLastWord) {
284-
lastLine += " ";
285-
continue; // Line
286-
} else if (!nextLineIsSmaller && !isLastWord) {
287-
if (!formObject.multiline) {
280+
let isWithNewLine = false;
281+
if (textSplit[i].length !== 1 && currWord !== textSplit[i].length - 1) {
282+
if (
283+
(textHeight + lineSpacing) * (lineCount + 2) + lineSpacing >
284+
height
285+
) {
288286
continue FontSize;
287+
}
288+
289+
lastLine += textSplit[i][currWord];
290+
isWithNewLine = true;
291+
lastWordInLine = i;
292+
i--;
293+
} else {
294+
lastLine += textSplit[i][currWord] + " ";
295+
lastLine =
296+
lastLine.substr(lastLine.length - 1) == " "
297+
? lastLine.substr(0, lastLine.length - 1)
298+
: lastLine;
299+
var key = parseInt(i);
300+
var nextLineIsSmaller = isSmallerThanWidth(key, lastLine, fontSize);
301+
var isLastWord = i >= textSplit.length - 1;
302+
303+
if (nextLineIsSmaller && !isLastWord) {
304+
lastLine += " ";
305+
currWord = 0;
306+
continue; // Line
307+
} else if (!nextLineIsSmaller && !isLastWord) {
308+
if (!formObject.multiline) {
309+
continue FontSize;
310+
} else {
311+
if (
312+
(textHeight + lineSpacing) * (lineCount + 2) + lineSpacing >
313+
height
314+
) {
315+
// If the Text is higher than the
316+
// FieldObject
317+
continue FontSize;
318+
}
319+
lastWordInLine = key;
320+
// go on
321+
}
322+
} else if (isLastWord) {
323+
lastWordInLine = key;
289324
} else {
290325
if (
326+
formObject.multiline &&
291327
(textHeight + lineSpacing) * (lineCount + 2) + lineSpacing >
292-
height
328+
height
293329
) {
294-
// If the Text is higher than the
295-
// FieldObject
330+
// If the Text is higher than the FieldObject
296331
continue FontSize;
297332
}
298-
lastWordInLine = key;
299-
// go on
300-
}
301-
} else if (isLastWord) {
302-
lastWordInLine = key;
303-
} else {
304-
if (
305-
formObject.multiline &&
306-
(textHeight + lineSpacing) * (lineCount + 2) + lineSpacing > height
307-
) {
308-
// If the Text is higher than the FieldObject
309-
continue FontSize;
310333
}
311334
}
335+
// Remove last blank
312336

313337
var line = "";
314338

315339
for (var x = firstWordInLine; x <= lastWordInLine; x++) {
316-
line += textSplit[x] + " ";
340+
var currLine = textSplit[x];
341+
if (formObject.multiline) {
342+
if (x === lastWordInLine) {
343+
line += currLine[currWord] + " ";
344+
currWord = (currWord + 1) % currLine.length;
345+
continue;
346+
}
347+
if (x === firstWordInLine) {
348+
line += currLine[currLine.length - 1] + " ";
349+
continue;
350+
}
351+
}
352+
line += currLine[0] + " ";
317353
}
318354

319355
// Remove last blank
@@ -347,7 +383,7 @@ var calculateX = function(formObject, text) {
347383

348384
// Reset for next iteration step
349385
lastLength = 0;
350-
firstWordInLine = lastWordInLine + 1;
386+
firstWordInLine = isWithNewLine ? lastWordInLine : lastWordInLine + 1;
351387
lineCount++;
352388

353389
lastLine = "";

test/reference/textfieldMultiline.pdf

3.56 KB
Binary file not shown.
3.66 KB
Binary file not shown.

test/specs/acroform.spec.js

+36
Original file line numberDiff line numberDiff line change
@@ -973,6 +973,42 @@ describe("Module: Acroform Integration Test", function() {
973973
comparePdf(doc.output(), "password.pdf", "acroform");
974974
});
975975

976+
it("Check multiline text", function() {
977+
var doc = new jsPDF({
978+
orientation: "p",
979+
unit: "mm",
980+
format: "a4",
981+
floatPrecision: 2
982+
});
983+
doc.text("TextField:", 10, 145);
984+
var textField = new TextField();
985+
textField.Rect = [50, 140, 100, 100];
986+
textField.multiline = true;
987+
textField.V = "A\nB\nC";
988+
989+
doc.addField(textField);
990+
991+
comparePdf(doc.output(), "textfieldMultiline.pdf", "acroform");
992+
});
993+
994+
it("Check multiline text in small form", function() {
995+
var doc = new jsPDF({
996+
orientation: "p",
997+
unit: "mm",
998+
format: "a4",
999+
floatPrecision: 2
1000+
});
1001+
doc.text("TextField:", 10, 145);
1002+
var textField = new TextField();
1003+
textField.Rect = [50, 140, 100, 15];
1004+
textField.multiline = true;
1005+
textField.V = "A\nLong line Long line Long line Long line Long line \nC";
1006+
1007+
doc.addField(textField);
1008+
1009+
comparePdf(doc.output(), "textfieldMultilineSmallForm.pdf", "acroform");
1010+
});
1011+
9761012
it("should add a RadioGroup Cross", function() {
9771013
var doc = new jsPDF({
9781014
orientation: "p",

0 commit comments

Comments
 (0)