UNPKG

@cantoo/pdf-lib

Version:

Create and modify PDF files with JavaScript

100 lines 4.19 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const tslib_1 = require("tslib"); const standard_fonts_1 = require("@pdf-lib/standard-fonts"); const PDFHexString_1 = tslib_1.__importDefault(require("../objects/PDFHexString")); const utils_1 = require("../../utils"); /** * A note of thanks to the developers of https://github.com/foliojs/pdfkit, as * this class borrows from: * https://github.com/foliojs/pdfkit/blob/f91bdd61c164a72ea06be1a43dc0a412afc3925f/lib/font/afm.coffee */ class StandardFontEmbedder { constructor(fontName, customName) { // prettier-ignore this.encoding = (fontName === standard_fonts_1.FontNames.ZapfDingbats ? standard_fonts_1.Encodings.ZapfDingbats : fontName === standard_fonts_1.FontNames.Symbol ? standard_fonts_1.Encodings.Symbol : standard_fonts_1.Encodings.WinAnsi); this.font = standard_fonts_1.Font.load(fontName); this.fontName = this.font.FontName; this.customName = customName; } /** * Encode the JavaScript string into this font. (JavaScript encodes strings in * Unicode, but standard fonts use either WinAnsi, ZapfDingbats, or Symbol * encodings) */ encodeText(text) { const glyphs = this.encodeTextAsGlyphs(text); const hexCodes = new Array(glyphs.length); for (let idx = 0, len = glyphs.length; idx < len; idx++) { hexCodes[idx] = (0, utils_1.toHexString)(glyphs[idx].code); } return PDFHexString_1.default.of(hexCodes.join('')); } widthOfTextAtSize(text, size) { const glyphs = this.encodeTextAsGlyphs(text); let totalWidth = 0; for (let idx = 0, len = glyphs.length; idx < len; idx++) { const left = glyphs[idx].name; const right = (glyphs[idx + 1] || {}).name; const kernAmount = this.font.getXAxisKerningForPair(left, right) || 0; totalWidth += this.widthOfGlyph(left) + kernAmount; } const scale = size / 1000; return totalWidth * scale; } heightOfFontAtSize(size, options = {}) { const { descender = true } = options; const { Ascender, Descender, FontBBox } = this.font; const yTop = Ascender || FontBBox[3]; const yBottom = Descender || FontBBox[1]; let height = yTop - yBottom; if (!descender) height += Descender || 0; return (height / 1000) * size; } sizeOfFontAtHeight(height) { const { Ascender, Descender, FontBBox } = this.font; const yTop = Ascender || FontBBox[3]; const yBottom = Descender || FontBBox[1]; return (1000 * height) / (yTop - yBottom); } embedIntoContext(context, ref) { const fontDict = context.obj({ Type: 'Font', Subtype: 'Type1', BaseFont: this.customName || this.fontName, Encoding: this.encoding === standard_fonts_1.Encodings.WinAnsi ? 'WinAnsiEncoding' : undefined, }); if (ref) { context.assign(ref, fontDict); return ref; } else { return context.register(fontDict); } } widthOfGlyph(glyphName) { // Default to 250 if font doesn't specify a width return this.font.getWidthOfGlyph(glyphName) || 250; } encodeTextAsGlyphs(text) { const codePoints = Array.from(text); const glyphs = new Array(codePoints.length); for (let idx = 0, len = codePoints.length; idx < len; idx++) { const codePoint = (0, utils_1.toCodePoint)(codePoints[idx]); try { glyphs[idx] = this.encoding.encodeUnicodeCodePoint(codePoint); } catch (error) { // Replace non-WinAnsi characters with a placeholder glyphs[idx] = this.encoding.encodeUnicodeCodePoint((0, utils_1.toCodePoint)('?')); } } return glyphs; } } StandardFontEmbedder.for = (fontName, customName) => new StandardFontEmbedder(fontName, customName); exports.default = StandardFontEmbedder; //# sourceMappingURL=StandardFontEmbedder.js.map