jsPDF 对齐文本
jsPDF justify text
我正在尝试对 jsPDF 库应用一些更改,以便能够调整文本。
我无法找到 Tw(字间距)的正确值。
在 jspdf.js (L:1413) 我添加了这段代码:
if (align) {
...
else if (align === 'justify') {
left = x;
}
else {
throw new Error('Unrecognized alignment option, use "center" or "right".');
}
prevX = x;
text = '(' + da[0];
let pdfPageWidth = this.internal.pageSize.width;
let wordSpacing;
if( align === 'justify' ) {
let fontSize = this.internal.getFontSize();
let nWords = da[0].trim().split(/\s+/).length;
let textWidth = this.getStringUnitWidth(da[0].replace(/\s+/g, '')) / this.internal.scaleFactor;
wordSpacing = (Math.max(0, (pdfPageWidth - textWidth) / Math.max(1, nWords - 1));
wordSpacing += ' Tw\n';
text = wordSpacing + text;
}
...
}
想法是通过执行 (pageWidth - textWidth) / numberOfWords -1 来提取 space 宽度。我找不到正确的单词 space。
输出示例
BT
/F1 16 Tf
18.4 TL
0 g
28.35 756.85 Td
19.00357142857142 Tw
(And a little bit it adélkfjalké.) Tj
ET
编码有问题吗?
感谢您的帮助。
我在 github 上回复了你
我根据您的建议将自己的理由代码写入了我重构的jsPDF。
看看...
https://github.com/MrRio/jsPDF/issues/1016#issuecomment-329957940
已编辑:
哦,等等,我可能可以帮助您直接回答。我想你只需要像这样改变它:
var wordSpacing = (Math.max(0, (pdfPageWidth - textWidth) / Math.max(1, nWords - 1)) * this.internal.scaleFactor);
if (align) {
...
else if (align === 'justify') {
var wordSpacingPerLine = [];
for (var i = 0, len = da.length; i < len; i++) {
wordSpacingPerLine.push(((this.internal.pageSize.width - lineWidths[i]) / (da[i].split(" ").length - 1) * k).toFixed(2));
}
}
else {
throw new Error('Unrecognized alignment option, use "center" or "right".');
}
prevX = x;
text = '(' + da[0];
let pdfPageWidth = this.internal.pageSize.width;
let wordSpacing;
if( align === 'justify' ) {
text = wordSpacingPerLine[0] + ' Tw\n' + text;
}
...
}
您必须为除最后一行以外的每一行添加特定的 WordSpacing。最后一行然后左对齐。
举个例子:
BT
/F1 16 Tf
18.4 TL
0 g
4.869500000212597 Tw
28.35 813.54 Td
(Lorem ipsum dolor sit amet, consetetur abore et dolore) Tj
3.5284444446334158 Tw
0.00 -18.40 Td
(magna aliquyam erat, sed diam voluptua. At vero eos et) Tj
2.0876000001700574 Tw
0.00 -18.40 Td
(accusam et justo duo dolores et ea rebum. Stet clita kasd) Tj
1.329500000212585 Tw
0.00 -18.40 Td
(gubergren, no sea takimata sanctus est Lorem ipsum dolor) Tj
1.329500000212585 Tw
0.00 -18.40 Td
(sit amet.) Tj
ET
经过多次尝试,我找到了有效的代码解决方案 :D。它也适用于文本数组作为参数。
} else if (align === 'justify') {
left = x;
}
else {
throw new Error(
'Unrecognized alignment option, use "center" or "right".'
);
}
prevX = x;
text = '(' + da[0];
var pdfPageWidth = this.internal.pageSize.width;
var wordSpacing;
var fontSize = this.internal.getFontSize();
if( align === 'justify' ) {
var nWords = da[0].trim().split(/\s+/).length;
var textWidth = this.getStringUnitWidth(da[0]) * fontSize / k;
wordSpacing = (Math.max(0, ((pdfPageWidth - x - marginRight) - textWidth) / Math.max(1, nWords - 1))) * k;
// Do not justify if wordSpacing is too high
wordSpacing = ( wordSpacing > 50 ? 0 : wordSpacing ) + ' Tw\n';
text = wordSpacing + text;
}
for (var i = 1, len = da.length; i < len; i++) {
var delta = maxLineLength - lineWidths[i];
if (align === "center") delta /= 2;
if (align === "justify") { // TODO: improve code duplication
delta = 0;
var nWords = da[i].trim().split(/\s+/).length;
var textWidth = this.getStringUnitWidth(da[i]) * fontSize / k;
wordSpacing = (Math.max(0, ((pdfPageWidth - x - marginRight) - textWidth) / Math.max(1, nWords - 1))) * k;
// Do not justify if wordSpacing is too high
wordSpacing = ( wordSpacing > 50 ? 0 : wordSpacing ) + ' Tw\n';
text += ") Tj\n" + ((left - prevX) + delta) + " -" + leading + " Td\n" + wordSpacing + "(" + da[i];
} else {
// T* = x-offset leading Td ( text )
text += ") Tj\n" + ((left - prevX) + delta) + " -" + leading + " Td (" + da[i];
}
prevX = left + delta;
}
} else {
text = ' 0 Tw\n (' + da.join(") Tj\nT* (");
}
这是我的PR
当使用自定义字体(ttf 等)时,可以使用 javascript 对齐文本以将所有单词放在正确的位置。参见 Whosebug justify text with custom font
我正在尝试对 jsPDF 库应用一些更改,以便能够调整文本。
我无法找到 Tw(字间距)的正确值。
在 jspdf.js (L:1413) 我添加了这段代码:
if (align) {
...
else if (align === 'justify') {
left = x;
}
else {
throw new Error('Unrecognized alignment option, use "center" or "right".');
}
prevX = x;
text = '(' + da[0];
let pdfPageWidth = this.internal.pageSize.width;
let wordSpacing;
if( align === 'justify' ) {
let fontSize = this.internal.getFontSize();
let nWords = da[0].trim().split(/\s+/).length;
let textWidth = this.getStringUnitWidth(da[0].replace(/\s+/g, '')) / this.internal.scaleFactor;
wordSpacing = (Math.max(0, (pdfPageWidth - textWidth) / Math.max(1, nWords - 1));
wordSpacing += ' Tw\n';
text = wordSpacing + text;
}
...
}
想法是通过执行 (pageWidth - textWidth) / numberOfWords -1 来提取 space 宽度。我找不到正确的单词 space。
输出示例
BT
/F1 16 Tf
18.4 TL
0 g
28.35 756.85 Td
19.00357142857142 Tw
(And a little bit it adélkfjalké.) Tj
ET
编码有问题吗?
感谢您的帮助。
我在 github 上回复了你 我根据您的建议将自己的理由代码写入了我重构的jsPDF。
看看...
https://github.com/MrRio/jsPDF/issues/1016#issuecomment-329957940
已编辑:
哦,等等,我可能可以帮助您直接回答。我想你只需要像这样改变它:
var wordSpacing = (Math.max(0, (pdfPageWidth - textWidth) / Math.max(1, nWords - 1)) * this.internal.scaleFactor);
if (align) {
...
else if (align === 'justify') {
var wordSpacingPerLine = [];
for (var i = 0, len = da.length; i < len; i++) {
wordSpacingPerLine.push(((this.internal.pageSize.width - lineWidths[i]) / (da[i].split(" ").length - 1) * k).toFixed(2));
}
}
else {
throw new Error('Unrecognized alignment option, use "center" or "right".');
}
prevX = x;
text = '(' + da[0];
let pdfPageWidth = this.internal.pageSize.width;
let wordSpacing;
if( align === 'justify' ) {
text = wordSpacingPerLine[0] + ' Tw\n' + text;
}
...
}
您必须为除最后一行以外的每一行添加特定的 WordSpacing。最后一行然后左对齐。
举个例子:
BT
/F1 16 Tf
18.4 TL
0 g
4.869500000212597 Tw
28.35 813.54 Td
(Lorem ipsum dolor sit amet, consetetur abore et dolore) Tj
3.5284444446334158 Tw
0.00 -18.40 Td
(magna aliquyam erat, sed diam voluptua. At vero eos et) Tj
2.0876000001700574 Tw
0.00 -18.40 Td
(accusam et justo duo dolores et ea rebum. Stet clita kasd) Tj
1.329500000212585 Tw
0.00 -18.40 Td
(gubergren, no sea takimata sanctus est Lorem ipsum dolor) Tj
1.329500000212585 Tw
0.00 -18.40 Td
(sit amet.) Tj
ET
经过多次尝试,我找到了有效的代码解决方案 :D。它也适用于文本数组作为参数。
} else if (align === 'justify') {
left = x;
}
else {
throw new Error(
'Unrecognized alignment option, use "center" or "right".'
);
}
prevX = x;
text = '(' + da[0];
var pdfPageWidth = this.internal.pageSize.width;
var wordSpacing;
var fontSize = this.internal.getFontSize();
if( align === 'justify' ) {
var nWords = da[0].trim().split(/\s+/).length;
var textWidth = this.getStringUnitWidth(da[0]) * fontSize / k;
wordSpacing = (Math.max(0, ((pdfPageWidth - x - marginRight) - textWidth) / Math.max(1, nWords - 1))) * k;
// Do not justify if wordSpacing is too high
wordSpacing = ( wordSpacing > 50 ? 0 : wordSpacing ) + ' Tw\n';
text = wordSpacing + text;
}
for (var i = 1, len = da.length; i < len; i++) {
var delta = maxLineLength - lineWidths[i];
if (align === "center") delta /= 2;
if (align === "justify") { // TODO: improve code duplication
delta = 0;
var nWords = da[i].trim().split(/\s+/).length;
var textWidth = this.getStringUnitWidth(da[i]) * fontSize / k;
wordSpacing = (Math.max(0, ((pdfPageWidth - x - marginRight) - textWidth) / Math.max(1, nWords - 1))) * k;
// Do not justify if wordSpacing is too high
wordSpacing = ( wordSpacing > 50 ? 0 : wordSpacing ) + ' Tw\n';
text += ") Tj\n" + ((left - prevX) + delta) + " -" + leading + " Td\n" + wordSpacing + "(" + da[i];
} else {
// T* = x-offset leading Td ( text )
text += ") Tj\n" + ((left - prevX) + delta) + " -" + leading + " Td (" + da[i];
}
prevX = left + delta;
}
} else {
text = ' 0 Tw\n (' + da.join(") Tj\nT* (");
}
这是我的PR
当使用自定义字体(ttf 等)时,可以使用 javascript 对齐文本以将所有单词放在正确的位置。参见 Whosebug justify text with custom font