Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

### Unreleased

- Reuse the glyph width and kerning tables of a standard font across documents instead of building them again for every document that uses it, which made a short document using two standard fonts more than twice as slow to create
- Fix `doc.table()` parsing a font passed as binary data (e.g. registered with `registerFont(name, uint8Array)`) again for every cell, when it restores the font after measuring and drawing the cell, which made tables with such fonts slower. A font loaded from the same `Uint8Array` is now reused without parsing it again
- Add `lineBreak: 'whitespace'` to `doc.text()`, which breaks a line only at whitespace, a soft hyphen or a zero-width space. The Unicode line breaking rules the wrapper follows also allow a break after a hyphen or a slash, so `design-system` or `https://github.com/foliojs/pdfkit` could be cut at a line end, and a text extractor that joins the lines, such as a résumé parser, reads two words
- Add an `objectStreams` option, which packs the objects that are not streams into compressed object streams and writes a cross-reference stream instead of the xref table, making documents with many such objects, e.g. tagged ones, much smaller. It requires a `pdfVersion` of `1.5` or higher, and cannot be used with encryption or PDF/A-1. Fixes #1810
Expand Down
10 changes: 9 additions & 1 deletion lib/font/standard.js
Original file line number Diff line number Diff line change
@@ -1,13 +1,21 @@
import AFMFont from './afm';
import PDFFont from '../font';

// AFMFont only reads its data, so every document can share the one built for
// a given font data instead of rebuilding its glyph width and kerning tables.
const afmFonts = new WeakMap();

class StandardFont extends PDFFont {
constructor(document, fontData, id) {
super();
this.document = document;
this.name = fontData.name;
this.id = id;
this.font = new AFMFont(fontData);
this.font = afmFonts.get(fontData);
if (!this.font) {
this.font = new AFMFont(fontData);
afmFonts.set(fontData, this.font);
}
({
ascender: this.ascender,
descender: this.descender,
Expand Down
10 changes: 10 additions & 0 deletions tests/unit/font.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -454,3 +454,13 @@ describe('binary font sources', () => {
expect(doc._font.id).toBe(first.id);
});
});

describe('standard font metrics', () => {
test('are shared across documents', () => {
const first = new PDFDocument().font('Helvetica-Bold')._font;
const second = new PDFDocument().font('Helvetica-Bold')._font;

expect(second).not.toBe(first);
expect(second.font).toBe(first.font);
});
});