Skip to content

Commit

Permalink
Implement justifying for unicode fonts (#3285)
Browse files Browse the repository at this point in the history
Co-authored-by: Lukas Holländer <lukas.hollaender@yworks.com>
  • Loading branch information
owenl131 and HackbrettXXX committed Feb 11, 2022
1 parent 7315ccb commit 2d9a919
Show file tree
Hide file tree
Showing 3 changed files with 63 additions and 14 deletions.
58 changes: 44 additions & 14 deletions src/jspdf.js
Expand Up @@ -3806,23 +3806,23 @@ function jsPDF(options) {
flags = Object.assign({ autoencode: true, noBOM: true }, options.flags);

var wordSpacingPerLine = [];

var findWidth = function(v) {
return (
(scope.getStringUnitWidth(v, {
font: activeFont,
charSpace: charSpace,
fontSize: activeFontSize,
doKerning: false
}) *
activeFontSize) /
scaleFactor
);
};
if (Object.prototype.toString.call(text) === "[object Array]") {
da = transformTextToSpecialArray(text);
var newY;
if (align !== "left") {
lineWidths = da.map(function(v) {
return (
(scope.getStringUnitWidth(v, {
font: activeFont,
charSpace: charSpace,
fontSize: activeFontSize,
doKerning: false
}) *
activeFontSize) /
scaleFactor
);
});
lineWidths = da.map(findWidth);
}
//The first line uses the "main" Td setting,
//and the subsequent lines are offset by the
Expand Down Expand Up @@ -3869,11 +3869,41 @@ function jsPDF(options) {
for (var h = 0; h < len; h++) {
text.push(da[h]);
}
} else if (align === "justify" && activeFont.encoding === "Identity-H") {
// when using unicode fonts, wordSpacePerLine does not apply
text = [];
len = da.length;
maxWidth = maxWidth !== 0 ? maxWidth : pageWidth;
let backToStartX = 0;
for (var l = 0; l < len; l++) {
newY = l === 0 ? getVerticalCoordinate(y) : -leading;
newX = l === 0 ? getHorizontalCoordinate(x) : backToStartX;
if (l < len - 1) {
let spacing = scale(
(maxWidth - lineWidths[l]) / (da[l].split(" ").length - 1)
);
let words = da[l].split(" ");
text.push([words[0] + " ", newX, newY]);
backToStartX = 0; // distance to reset back to the left
for (let i = 1; i < words.length; i++) {
let shiftAmount =
(findWidth(words[i - 1] + " " + words[i]) -
findWidth(words[i])) *
scaleFactor +
spacing;
if (i == words.length - 1) text.push([words[i], shiftAmount, 0]);
else text.push([words[i] + " ", shiftAmount, 0]);
backToStartX -= shiftAmount;
}
} else {
text.push([da[l], newX, newY]);
}
}
text.push(["", backToStartX, 0]);
} else if (align === "justify") {
text = [];
len = da.length;
maxWidth = maxWidth !== 0 ? maxWidth : pageWidth;

for (var l = 0; l < len; l++) {
newY = l === 0 ? getVerticalCoordinate(y) : -leading;
newX = l === 0 ? getHorizontalCoordinate(x) : 0;
Expand Down
Binary file added test/reference/justify-custom-font.pdf
Binary file not shown.
19 changes: 19 additions & 0 deletions test/specs/text.spec.js
Expand Up @@ -175,6 +175,25 @@ break`
comparePdf(doc.output(), "alignment.pdf", "text");
});

it("should justify custom font", () => {
const doc = jsPDF({ floatPrecision: 2 });
var PTSans;
if (typeof global === "object" && global.isNode === true) {
PTSans = doc.loadFile("./test/reference/PTSans.ttf");
} else {
PTSans = doc.loadFile("base/test/reference/PTSans.ttf");
}
doc.addFileToVFS("PTSans.ttf", PTSans);
doc.addFont("PTSans.ttf", "PTSans", "normal");
doc.setFont("PTSans");
doc.setFontSize(10);
doc.text("А ну чики брики и в дамки! А ну чики брики и в дамки! А ну чики брики и в дамки! А ну чики брики и в дамки! А ну чики брики и в дамки! А ну чики брики и в дамки! А ну чики брики и в дамки! А ну чики брики и в дамки! А ну чики брики и в дамки! ", 10, 10, {
align: "justify",
maxWidth: 100,
});
comparePdf(doc.output(), "justify-custom-font.pdf", "text");
});

it("should throw an error if not a string", () => {
expect(() => {
const doc = jsPDF({ floatPrecision: 2 });
Expand Down

0 comments on commit 2d9a919

Please sign in to comment.