From 15087ea8c32b9f170d114ad3da193e9262bb101d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luiz=20Am=C3=A9rico=20Pereira=20C=C3=A2mara?= Date: Sat, 12 Apr 2025 12:43:17 -0300 Subject: [PATCH] Cleanup / simplify code --- lib/document.js | 30 ++++++++++----------- lib/font.js | 7 ++--- lib/line_wrapper.js | 35 +++++++++++++++--------- lib/mixins/color.js | 12 ++++----- lib/mixins/fonts.js | 35 +++++++++++++++--------- lib/mixins/images.js | 24 ++++++++--------- lib/mixins/outline.js | 4 +-- lib/mixins/text.js | 62 ++++++++++++++++++++++++++----------------- lib/mixins/vector.js | 33 ++++++++++++++--------- lib/reference.js | 4 +-- 10 files changed, 141 insertions(+), 105 deletions(-) diff --git a/lib/document.js b/lib/document.js index 45935ea..9433209 100644 --- a/lib/document.js +++ b/lib/document.js @@ -64,17 +64,17 @@ class PDFDocument extends stream.Readable { const Pages = this.ref({ Type: 'Pages', Count: 0, - Kids: [] + Kids: [], }); const Names = this.ref({ - Dests: new PDFNameTree() + Dests: new PDFNameTree(), }); this._root = this.ref({ Type: 'Catalog', Pages, - Names + Names, }); if (this.options.lang) { @@ -100,7 +100,7 @@ class PDFDocument extends stream.Readable { this.info = { Producer: 'PDFKit', Creator: 'PDFKit', - CreationDate: new Date() + CreationDate: new Date(), }; if (this.options.info) { @@ -112,7 +112,7 @@ class PDFDocument extends stream.Readable { if (this.options.displayTitle) { this._root.data.ViewerPreferences = this.ref({ - DisplayDocTitle: true + DisplayDocTitle: true, }); } @@ -188,7 +188,7 @@ class PDFDocument extends stream.Readable { throw new Error( `switchToPage(${n}) out of bounds, current buffer covers pages ${ this._pageBufferStart - } to ${this._pageBufferStart + this._pageBuffer.length - 1}` + } to ${this._pageBufferStart + this._pageBuffer.length - 1}`, ); } @@ -222,7 +222,7 @@ class PDFDocument extends stream.Readable { if (!this._root.data.Names.data.EmbeddedFiles) { // disabling /Limits for this tree fixes attachments not showing in Adobe Reader this._root.data.Names.data.EmbeddedFiles = new PDFNameTree({ - limits: false + limits: false, }); } @@ -236,7 +236,7 @@ class PDFDocument extends stream.Readable { } let data = { JS: new String(js), - S: 'JavaScript' + S: 'JavaScript', }; this._root.data.Names.data.JavaScript.add(name, data); } @@ -257,7 +257,7 @@ class PDFDocument extends stream.Readable { } this.push(data); - return (this._offset += data.length); + this._offset += data.length; } addContent(data) { @@ -269,7 +269,7 @@ class PDFDocument extends stream.Readable { this._offsets[ref.id - 1] = ref.offset; if (--this._waiting === 0 && this._ended) { this._finalize(); - return (this._ended = false); + this._ended = false; } } @@ -319,9 +319,9 @@ class PDFDocument extends stream.Readable { } if (this._waiting === 0) { - return this._finalize(); + this._finalize(); } else { - return (this._ended = true); + this._ended = true; } } @@ -342,7 +342,7 @@ class PDFDocument extends stream.Readable { Size: this._offsets.length + 1, Root: this._root, Info: this._info, - ID: [this._id, this._id] + ID: [this._id, this._id], }; if (this._security) { trailer.Encrypt = this._security.dictionary; @@ -356,7 +356,7 @@ class PDFDocument extends stream.Readable { this._write('%%EOF'); // end the stream - return this.push(null); + this.push(null); } toString() { @@ -364,7 +364,7 @@ class PDFDocument extends stream.Readable { } } -const mixin = methods => { +const mixin = (methods) => { Object.assign(PDFDocument.prototype, methods); }; diff --git a/lib/font.js b/lib/font.js index b37bc55..c0e098d 100644 --- a/lib/font.js +++ b/lib/font.js @@ -21,17 +21,14 @@ class PDFFont { } this.embed(); - return (this.embedded = true); + this.embedded = true; } embed() { throw new Error('Must be implemented by subclasses'); } - lineHeight(size, includeGap) { - if (includeGap == null) { - includeGap = false; - } + lineHeight(size, includeGap = false) { const gap = includeGap ? this.lineGap : 0; return ((this.ascender + gap - this.descender) / 1000) * size; } diff --git a/lib/line_wrapper.js b/lib/line_wrapper.js index d564c34..e455640 100644 --- a/lib/line_wrapper.js +++ b/lib/line_wrapper.js @@ -11,11 +11,19 @@ class LineWrapper extends EventEmitter { this.document = document; this.horizontalScaling = options.horizontalScaling || 100; this.indent = ((options.indent || 0) * this.horizontalScaling) / 100; - this.characterSpacing = ((options.characterSpacing || 0) * this.horizontalScaling) / 100; - this.wordSpacing = ((options.wordSpacing === 0) * this.horizontalScaling) / 100; + this.characterSpacing = + ((options.characterSpacing || 0) * this.horizontalScaling) / 100; + this.wordSpacing = + ((options.wordSpacing === 0) * this.horizontalScaling) / 100; this.columns = options.columns || 1; - this.columnGap = ((options.columnGap != null ? options.columnGap : 18) * this.horizontalScaling) / 100; // 1/4 inch - this.lineWidth = (((options.width * this.horizontalScaling) / 100) - (this.columnGap * (this.columns - 1))) / this.columns; + this.columnGap = + ((options.columnGap != null ? options.columnGap : 18) * + this.horizontalScaling) / + 100; // 1/4 inch + this.lineWidth = + ((options.width * this.horizontalScaling) / 100 - + this.columnGap * (this.columns - 1)) / + this.columns; this.spaceLeft = this.lineWidth; this.startX = this.document.x; this.startY = this.document.y; @@ -33,7 +41,7 @@ class LineWrapper extends EventEmitter { } // handle paragraph indents - this.on('firstLine', options => { + this.on('firstLine', (options) => { // if this is the first line of the text segment, and // we're continuing where we left off, indent that much // otherwise use the user specified indent option @@ -48,27 +56,27 @@ class LineWrapper extends EventEmitter { } // otherwise we start the next line without indent - return this.once('line', () => { + this.once('line', () => { this.document.x -= indent; this.lineWidth += indent; if (options.continued && !this.continuedX) { this.continuedX = this.indent; } if (!options.continued) { - return (this.continuedX = 0); + this.continuedX = 0; } }); }); // handle left aligning last lines of paragraphs - this.on('lastLine', options => { + this.on('lastLine', (options) => { const { align } = options; if (align === 'justify') { options.align = 'left'; } this.lastLine = true; - return this.once('line', () => { + this.once('line', () => { this.document.y += options.paragraphGap || 0; options.align = align; return (this.lastLine = false); @@ -102,7 +110,7 @@ class LineWrapper extends EventEmitter { var shouldContinue; let word = text.slice( (last != null ? last.position : undefined) || 0, - bk.position + bk.position, ); let w = wordWidths[word] != null @@ -178,7 +186,8 @@ class LineWrapper extends EventEmitter { this.indent = (options.indent * this.horizontalScaling) / 100; } if (options.characterSpacing != null) { - this.characterSpacing = (options.characterSpacing * this.horizontalScaling) / 100; + this.characterSpacing = + (options.characterSpacing * this.horizontalScaling) / 100; } if (options.wordSpacing != null) { this.wordSpacing = (options.wordSpacing * this.horizontalScaling) / 100; @@ -319,9 +328,9 @@ class LineWrapper extends EventEmitter { this.continuedX = 0; } this.continuedX += options.textWidth || 0; - return (this.document.y = y); + this.document.y = y; } else { - return (this.document.x = this.startX); + this.document.x = this.startX; } } diff --git a/lib/mixins/color.js b/lib/mixins/color.js index 8b11929..42ce1b4 100644 --- a/lib/mixins/color.js +++ b/lib/mixins/color.js @@ -12,7 +12,7 @@ export default { this._opacityRegistry = {}; this._opacityCount = 0; this._patternCount = 0; - return (this._gradCount = 0); + this._gradCount = 0; }, _normalizeColor(color) { @@ -21,7 +21,7 @@ export default { if (color.length === 4) { color = color.replace( /#([0-9A-F])([0-9A-F])([0-9A-F])/i, - '#$1$1$2$2$3$3' + '#$1$1$2$2$3$3', ); } const hex = parseInt(color.slice(1), 16); @@ -36,10 +36,10 @@ export default { if (Array.isArray(color)) { // RGB if (color.length === 3) { - color = color.map(part => part / 255); + color = color.map((part) => part / 255); // CMYK } else if (color.length === 4) { - color = color.map(part => part / 100); + color = color.map((part) => part / 100); } return color; } @@ -181,7 +181,7 @@ export default { const color = new SpotColor(this, name, C, M, Y, K); this.spotColors[name] = color; return this; - } + }, }; var namedColors = { @@ -331,5 +331,5 @@ var namedColors = { white: [255, 255, 255], whitesmoke: [245, 245, 245], yellow: [255, 255, 0], - yellowgreen: [154, 205, 50] + yellowgreen: [154, 205, 50], }; diff --git a/lib/mixins/fonts.js b/lib/mixins/fonts.js index 314a864..9b8d915 100644 --- a/lib/mixins/fonts.js +++ b/lib/mixins/fonts.js @@ -3,23 +3,29 @@ import { CM_TO_IN, IN_TO_PT, MM_TO_CM, PC_TO_PT, PX_TO_IN } from '../utils'; const isEqualFont = (font1, font2) => { // compare font checksum - if (font1.font._tables?.head?.checkSumAdjustment !== font2.font._tables?.head?.checkSumAdjustment) { + if ( + font1.font._tables?.head?.checkSumAdjustment !== + font2.font._tables?.head?.checkSumAdjustment + ) { return false; } // compare font name table - if (JSON.stringify(font1.font._tables?.name?.records) !== JSON.stringify(font2.font._tables?.name?.records)) { + if ( + JSON.stringify(font1.font._tables?.name?.records) !== + JSON.stringify(font2.font._tables?.name?.records) + ) { return false; } return true; -} +}; export default { initFonts( defaultFont = 'Helvetica', defaultFontFamily = null, - defaultFontSize = 12 + defaultFontSize = 12, ) { // Lookup table for embedded fonts this._fontFamilies = {}; @@ -80,7 +86,10 @@ export default { // check for existing font familes with the same name already in the PDF // useful if the font was passed as a buffer - if ((font = this._fontFamilies[this._font.name]) && isEqualFont(this._font, font)) { + if ( + (font = this._fontFamilies[this._font.name]) && + isEqualFont(this._font, font) + ) { this._font = font; return this; } @@ -103,16 +112,13 @@ export default { }, currentLineHeight(includeGap) { - if (includeGap == null) { - includeGap = false; - } return this._font.lineHeight(this._fontSize, includeGap); }, registerFont(name, src, family) { this._registeredFonts[name] = { src, - family + family, }; return this; @@ -128,7 +134,12 @@ export default { * * @returns number */ - sizeToPoint(size, defaultValue = 0, page = this.page, percentageWidth = undefined) { + sizeToPoint( + size, + defaultValue = 0, + page = this.page, + percentageWidth = undefined, + ) { if (!percentageWidth) percentageWidth = this._fontSize; if (typeof defaultValue !== 'number') defaultValue = this.sizeToPoint(defaultValue); @@ -137,7 +148,7 @@ export default { if (typeof size === 'boolean') return Number(size); const match = String(size).match( - /((\d+)?(\.\d+)?)(em|in|px|cm|mm|pc|ex|ch|rem|vw|vh|vmin|vmax|%|pt)?/ + /((\d+)?(\.\d+)?)(em|in|px|cm|mm|pc|ex|ch|rem|vw|vh|vmin|vmax|%|pt)?/, ); if (!match) throw new Error(`Unsupported size '${size}'`); let multiplier; @@ -190,5 +201,5 @@ export default { } return multiplier * Number(match[1]); - } + }, }; diff --git a/lib/mixins/images.js b/lib/mixins/images.js index 670a582..8486b9b 100644 --- a/lib/mixins/images.js +++ b/lib/mixins/images.js @@ -3,7 +3,7 @@ import PDFImage from '../image'; export default { initImages() { this._imageRegistry = {}; - return (this._imageCount = 0); + this._imageCount = 0; }, image(src, x, y, options = {}) { @@ -146,7 +146,8 @@ export default { originX = x; originY = y; - [wTransform, hTransform] = [h, w]; + wTransform = h; + hTransform = w; yTransform -= hTransform; rotateAngle = 90; @@ -156,8 +157,8 @@ export default { originX = x; originY = y; - [wTransform, hTransform] = [h, w]; - hTransform = -hTransform; + wTransform = h; + hTransform = -w; rotateAngle = 90; break; @@ -166,10 +167,9 @@ export default { originX = x; originY = y; - [wTransform, hTransform] = [h, w]; - hTransform = -hTransform; - wTransform = -wTransform; - xTransform -= wTransform; + hTransform = -w; + wTransform = -h; + xTransform += h; rotateAngle = 90; break; @@ -178,10 +178,10 @@ export default { originX = x; originY = y; - [wTransform, hTransform] = [h, w]; - hTransform = -hTransform; - xTransform -= wTransform; - yTransform -= hTransform; + wTransform = h; + hTransform = -w; + xTransform -= h; + yTransform += w; rotateAngle = -90; break; diff --git a/lib/mixins/outline.js b/lib/mixins/outline.js index 1da603e..58a6dad 100644 --- a/lib/mixins/outline.js +++ b/lib/mixins/outline.js @@ -2,7 +2,7 @@ import PDFOutline from '../outline'; export default { initOutline() { - return (this.outline = new PDFOutline(this, null, null, null)); + this.outline = new PDFOutline(this, null, null, null); }, endOutline() { @@ -11,5 +11,5 @@ export default { this._root.data.Outlines = this.outline.dictionary; return (this._root.data.PageMode = 'UseOutlines'); } - } + }, }; diff --git a/lib/mixins/text.js b/lib/mixins/text.js index ddd984b..168d390 100644 --- a/lib/mixins/text.js +++ b/lib/mixins/text.js @@ -10,7 +10,7 @@ export default { // Current coordinates this.x = 0; this.y = 0; - return (this._lineGap = 0); + this._lineGap = 0; }, lineGap(_lineGap) { @@ -47,8 +47,11 @@ export default { const addStructure = () => { if (options.structParent) { - options.structParent.add(this.struct(options.structType || 'P', - [this.markStructureContent(options.structType || 'P')])); + options.structParent.add( + this.struct(options.structType || 'P', [ + this.markStructureContent(options.structType || 'P'), + ]), + ); } }; @@ -91,7 +94,12 @@ export default { widthOfString(string, options = {}) { const horizontalScaling = options.horizontalScaling || 100; - return ((this._font.widthOfString(string, this._fontSize, options.features) + (options.characterSpacing || 0) * (string.length - 1)) * horizontalScaling) / 100; + return ( + ((this._font.widthOfString(string, this._fontSize, options.features) + + (options.characterSpacing || 0) * (string.length - 1)) * + horizontalScaling) / + 100 + ); }, /** @@ -122,7 +130,7 @@ export default { if (options.width) { let wrapper = new LineWrapper(this, options); wrapper.on('line', (text, options) => { - this.y+=lineHeight; + this.y += lineHeight; text = text.replace(/\n/g, ''); if (text.length) { @@ -234,7 +242,7 @@ export default { const lineGap = options.lineGap || this._lineGap || 0; this._text(text, this.x, this.y, options, () => { - return (this.y += this.currentLineHeight(true) + lineGap); + this.y += this.currentLineHeight(true) + lineGap; }); const height = this.y - y; @@ -324,8 +332,11 @@ export default { } if (item && (labelType || bodyType)) { - item.add(this.struct(labelType || bodyType, - [this.markStructureContent(labelType || bodyType)])); + item.add( + this.struct(labelType || bodyType, [ + this.markStructureContent(labelType || bodyType), + ]), + ); } switch (listType) { case 'bullet': @@ -340,7 +351,9 @@ export default { } if (item && labelType && bodyType) { - item.add(this.struct(bodyType, [this.markStructureContent(bodyType)])); + item.add( + this.struct(bodyType, [this.markStructureContent(bodyType)]), + ); } if (item && item !== options.structParent) { item.end(); @@ -350,19 +363,18 @@ export default { wrapper.on('sectionStart', () => { const pos = indent + itemIndent * (level - 1); this.x += pos; - return (wrapper.lineWidth -= pos); + wrapper.lineWidth -= pos; }); wrapper.on('sectionEnd', () => { const pos = indent + itemIndent * (level - 1); this.x -= pos; - return (wrapper.lineWidth += pos); + wrapper.lineWidth += pos; }); wrapper.wrap(listItem, options); }; - for (let i = 0; i < items.length; i++) { drawListItem.call(this, items[i], i); } @@ -426,9 +438,9 @@ export default { const lineGap = options.lineGap || this._lineGap || 0; if (!wrapper) { - return (this.x += this.widthOfString(text, options)); + this.x += this.widthOfString(text, options); } else { - return (this.y += this.currentLineHeight(true) + lineGap); + this.y += this.currentLineHeight(true) + lineGap; } }, @@ -465,7 +477,7 @@ export default { wordSpacing = Math.max( 0, (options.lineWidth - textWidth) / Math.max(1, words.length - 1) - - spaceWidth + spaceWidth, ); break; } @@ -533,7 +545,7 @@ export default { this._fontSize < 10 ? 0.5 : Math.floor(this._fontSize / 10); this.lineWidth(lineWidth); - let lineY = (y + this.currentLineHeight()) - lineWidth + let lineY = y + this.currentLineHeight() - lineWidth; this.moveTo(x, lineY); this.lineTo(x + renderedWidth, lineY); this.stroke(); @@ -621,7 +633,7 @@ export default { for (let word of words) { const [encodedWord, positionsWord] = this._font.encode( word, - options.features + options.features, ); encoded = encoded.concat(encodedWord); positions = positions.concat(positionsWord); @@ -647,7 +659,7 @@ export default { let hadOffset = false; // Adds a segment of text to the TJ command buffer - const addSegment = cur => { + const addSegment = (cur) => { if (last < cur) { const hex = encoded.slice(last, cur).join(''); const advance = @@ -655,16 +667,16 @@ export default { commands.push(`<${hex}> ${number(-advance)}`); } - return (last = cur); + last = cur; }; // Flushes the current TJ commands to the output stream - const flush = i => { + const flush = (i) => { addSegment(i); if (commands.length > 0) { this.addContent(`[${commands.join(' ')}] TJ`); - return (commands.length = 0); + commands.length = 0; } }; @@ -679,8 +691,8 @@ export default { // Move the text position and flush just the current character this.addContent( `1 0 0 1 ${number(x + pos.xOffset * scale)} ${number( - y + pos.yOffset * scale - )} Tm` + y + pos.yOffset * scale, + )} Tm`, ); flush(i + 1); @@ -708,6 +720,6 @@ export default { this.addContent('ET'); // restore flipped coordinate system - return this.restore(); - } + this.restore(); + }, }; diff --git a/lib/mixins/vector.js b/lib/mixins/vector.js index c042626..b95ecfa 100644 --- a/lib/mixins/vector.js +++ b/lib/mixins/vector.js @@ -9,7 +9,7 @@ const KAPPA = 4.0 * ((Math.sqrt(2) - 1.0) / 3.0); export default { initVector() { this._ctm = [1, 0, 0, 1, 0, 0]; // current transformation matrix - return (this._ctmStack = []); + this._ctmStack = []; }, save() { @@ -34,7 +34,7 @@ export default { _CAP_STYLES: { BUTT: 0, ROUND: 1, - SQUARE: 2 + SQUARE: 2, }, lineCap(c) { @@ -47,7 +47,7 @@ export default { _JOIN_STYLES: { MITER: 0, ROUND: 1, - BEVEL: 2 + BEVEL: 2, }, lineJoin(j) { @@ -67,12 +67,12 @@ export default { length = [length, options.space || length]; } - const valid = length.every(x => Number.isFinite(x) && x > 0); + const valid = length.every((x) => Number.isFinite(x) && x > 0); if (!valid) { throw new Error( `dash(${JSON.stringify(originalLength)}, ${JSON.stringify( - options - )}) invalid, lengths must be numeric and greater than zero` + options, + )}) invalid, lengths must be numeric and greater than zero`, ); } @@ -95,20 +95,20 @@ export default { bezierCurveTo(cp1x, cp1y, cp2x, cp2y, x, y) { return this.addContent( `${number(cp1x)} ${number(cp1y)} ${number(cp2x)} ${number(cp2y)} ${number( - x - )} ${number(y)} c` + x, + )} ${number(y)} c`, ); }, quadraticCurveTo(cpx, cpy, x, y) { return this.addContent( - `${number(cpx)} ${number(cpy)} ${number(x)} ${number(y)} v` + `${number(cpx)} ${number(cpy)} ${number(x)} ${number(y)} v`, ); }, rect(x, y, w, h) { return this.addContent( - `${number(x)} ${number(y)} ${number(w)} ${number(h)} re` + `${number(x)} ${number(y)} ${number(w)} ${number(h)} re`, ); }, @@ -289,7 +289,14 @@ export default { transform(m11, m12, m21, m22, dx, dy) { // keep track of the current transformation matrix - if (m11 === 1 && m12 === 0 && m21 === 0 && m22 === 1 && dx === 0 && dy === 0) { + if ( + m11 === 1 && + m12 === 0 && + m21 === 0 && + m22 === 1 && + dx === 0 && + dy === 0 + ) { // Ignore identity transforms return this; } @@ -302,7 +309,7 @@ export default { m[4] = m0 * dx + m2 * dy + m4; m[5] = m1 * dx + m3 * dy + m5; - const values = [m11, m12, m21, m22, dx, dy].map(v => number(v)).join(' '); + const values = [m11, m12, m21, m22, dx, dy].map((v) => number(v)).join(' '); return this.addContent(`${values} cm`); }, @@ -346,5 +353,5 @@ export default { } return this.transform(xFactor, 0, 0, yFactor, x, y); - } + }, }; diff --git a/lib/reference.js b/lib/reference.js index ad26e79..9da6ff4 100644 --- a/lib/reference.js +++ b/lib/reference.js @@ -31,7 +31,7 @@ class PDFReference extends PDFAbstractReference { this.buffer.push(chunk); this.data.Length += chunk.length; if (this.compress) { - return (this.data.Filter = 'FlateDecode'); + this.data.Filter = 'FlateDecode'; } } @@ -39,7 +39,7 @@ class PDFReference extends PDFAbstractReference { if (chunk) { this.write(chunk); } - return this.finalize(); + this.finalize(); } finalize() {