-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathfu-pdf.js
85 lines (65 loc) · 2.96 KB
/
fu-pdf.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
class FuPdf {
constructor(paperSchemaJson, evaluator, backgroundPdfArrayBuffer = null, fontArrayBuffers = []) {
this.paperSchema = paperSchemaJson;
this.mmx = 1;
this.mmy = 1;
this.evaluator = evaluator;
this.backgroundPdfArrayBuffer = backgroundPdfArrayBuffer;
this.fontArrayBuffers = fontArrayBuffers;
this.fonts = {};
}
async createPdf(jsonDataObj) {
let pdfDoc = null;
let page = null;
if (jsonDataObj.get('@form-background')) {
pdfDoc = await PDFLib.PDFDocument.load(this.backgroundPdfArrayBuffer);
page = pdfDoc.getPages()[0];
} else {
pdfDoc = await PDFLib.PDFDocument.create();
page = pdfDoc.addPage(PDFLib.PageSizes.A4);
}
await pdfDoc.registerFontkit(fontkit);
let font = null;
for(let f of this.fontArrayBuffers) {
this.fonts[f.name] = await pdfDoc.embedFont(f.data);
}
this.mmx = page.getWidth() / 210;
this.mmy = page.getHeight() / 297;
this._fillTexts(page, font, jsonDataObj);
return await pdfDoc.save();
}
static _mm2pt(size) {
return size * 2.835;
}
_fillTexts(page, font, jsonDataObj) {
this.paperSchema.positioning.forEach(item => {
if(item['type'] !== 'text') return;
let x = item.pos.x;
let y = item.pos.y;
let value = item.value;
let fontFace = this._pickAttr(item, 'font-face', this.paperSchema.global['font-family'])
let fontSize = this._pickAttr(item, 'font-size', this.paperSchema.global['font-size']);
let lineHeight = this._pickAttr(item, 'line-height', this.paperSchema.global['line-height']);
let textAnchor = this._pickAttr(item, 'text-anchor', this.paperSchema.global['text-anchor']);
let fontSizePt = FuPdf._mm2pt(fontSize);
let lineHeightEm = parseInt(lineHeight.replace(/em$/, ''));
let lineHeightPx = lineHeightEm * this.fonts[fontFace].heightAtSize(fontSize)
let text = this.evaluator.templateValue(jsonDataObj.data(), value);
let textLines = text.split('\n');
textLines.forEach((line, idx) => this._drawLine(page, x, y, line, idx, lineHeightPx, fontFace, fontSize, textAnchor));
})
}
_drawLine(page, x, y, text, lineIndex, lineHeight, fontFace, fontSize, textAnchor) {
let textWidth = this.fonts[fontFace].widthOfTextAtSize(text, fontSize);
let anchorShiftX = {'start': 0, 'middle': textWidth / 2, 'end': textWidth }[textAnchor] || 0;
page.drawText(text, {
x: x * this.mmx - anchorShiftX,
y: page.getHeight() - y * this.mmy - lineHeight * lineIndex,
size: fontSize,
font: this.fonts[fontFace]
});
}
_pickAttr(item, name, defaultValue) {
return [item[name], this.paperSchema.global[name], defaultValue].find(x => x);
}
}