From the specs https://www.npmjs.com/package/pdf-lib#embed-font-and-measure-text

pdf-lib relies on a sister module to support embedding custom fonts: @pdf-lib/fontkit. You must add the @pdf-lib/fontkit module to your project and register it using pdfDoc.registerFontkit(...) before embedding custom fonts.

We have to npm i --save @pdf-lib/fontkit and we have to have source from where which we will read the font. In my case I have added .otf file in project and loaded font. Files are structured like on the image:

import path from 'path';
import fs from 'fs';
import {PDFDocument, PDFForm, StandardFonts, PDFFont} from 'pdf-lib';
import fontkit from '@pdf-lib/fontkit';

const pdfBytes = fs.readFileSync(path.join(__dirname, `/w_template/` + fileName + '.pdf'));
const pdfDoc = await PDFDocument.load(pdfBytes);

pdfDoc.registerFontkit(fontkit);
//load font and embed it to pdf document
const fontBytes = fs.readFileSync(path.join(__dirname, 'HouschkaHead-BoldItalic.otf'));
const customFont = await pdfDoc.embedFont(fontBytes);

const form = pdfDoc.getForm();
const textField = form.getTextField('signature');
textField.setFontSize(11);
textField.setText('stefan z');
textField.updateAppearances(customFont);

// form flatten is available from v1.16.0 and it makes form read-only (not editable)
form.flatten();
const modifiedPdf = await pdfDoc.save();

And this is the final result: check how the signature input form field is different from rest of input fields which are filled with default font Bonus: if you want to play with color of the text of inputs in form, this is what I have found while digging more under the library source code (it might be not optimal, but it can give you starting point for more things):

import {setFillingRgbColor} from 'pdf-lib'

const textField = form.getTextField(fieldName);
const da = textField.acroField.getDefaultAppearance() ?? '';
const newDa = da + '\n' + setFillingRgbColor(1, 0, 0).toString(); 
textField.acroField.setDefaultAppearance(newDa);

Answer from Stefan on Stack Overflow
Top answer
1 of 3
22

From the specs https://www.npmjs.com/package/pdf-lib#embed-font-and-measure-text

pdf-lib relies on a sister module to support embedding custom fonts: @pdf-lib/fontkit. You must add the @pdf-lib/fontkit module to your project and register it using pdfDoc.registerFontkit(...) before embedding custom fonts.

We have to npm i --save @pdf-lib/fontkit and we have to have source from where which we will read the font. In my case I have added .otf file in project and loaded font. Files are structured like on the image:

import path from 'path';
import fs from 'fs';
import {PDFDocument, PDFForm, StandardFonts, PDFFont} from 'pdf-lib';
import fontkit from '@pdf-lib/fontkit';

const pdfBytes = fs.readFileSync(path.join(__dirname, `/w_template/` + fileName + '.pdf'));
const pdfDoc = await PDFDocument.load(pdfBytes);

pdfDoc.registerFontkit(fontkit);
//load font and embed it to pdf document
const fontBytes = fs.readFileSync(path.join(__dirname, 'HouschkaHead-BoldItalic.otf'));
const customFont = await pdfDoc.embedFont(fontBytes);

const form = pdfDoc.getForm();
const textField = form.getTextField('signature');
textField.setFontSize(11);
textField.setText('stefan z');
textField.updateAppearances(customFont);

// form flatten is available from v1.16.0 and it makes form read-only (not editable)
form.flatten();
const modifiedPdf = await pdfDoc.save();

And this is the final result: check how the signature input form field is different from rest of input fields which are filled with default font Bonus: if you want to play with color of the text of inputs in form, this is what I have found while digging more under the library source code (it might be not optimal, but it can give you starting point for more things):

import {setFillingRgbColor} from 'pdf-lib'

const textField = form.getTextField(fieldName);
const da = textField.acroField.getDefaultAppearance() ?? '';
const newDa = da + '\n' + setFillingRgbColor(1, 0, 0).toString(); 
textField.acroField.setDefaultAppearance(newDa);

2 of 3
7

If anyone is struggling to change the fontSize in filling text fields using the latest inbuilt function called setFontSize(). You can use this approach.

const { PDFDocument, setFontAndSize } = require('pdf-lib');

   const pdfDoc = await PDFDocument.load(file);
   const form = pdfDoc.getForm();

const textField = form.getTextField('106Mobile.1');
    textField.setText('This works fine');
    const da = textField.acroField.getDefaultAppearance() ?? '';
    const newDa = da + '\n' + setFontAndSize('Courier', 8).toString(); //setFontAndSize() method came to resuce
    textField.acroField.setDefaultAppearance(newDa);

I had to use this because I got an error saying

No /DA (default appearance) entry found for field: 106Title.1

when setting font sizes to some text fields (not all of it). But I degenerately had those text fields. Fixed it using the above workaround.

🌐
GitHub
github.com › Hopding › pdf-lib
GitHub - Hopding/pdf-lib: Create and modify PDF documents in any JavaScript environment
Here's a slightly more complicated example demonstrating how to embed a font and measure text in Deno: import { degrees, PDFDocument, rgb, StandardFonts, } from 'https://cdn.skypack.dev/pdf-lib@^1.11.1?dts'; import fontkit from 'https://cdn.skypack.dev/@pdf-lib/fontkit@^1.0.0?dts'; const url = 'https://pdf-lib.js.org/assets/ubuntu/Ubuntu-R.ttf'; const fontBytes = await fetch(url).then((res) => res.arrayBuffer()); const pdfDoc = await PDFDocument.create(); pdfDoc.registerFontkit(fontkit); const customFont = await pdfDoc.embedFont(fontBytes); const page = pdfDoc.addPage(); const text = 'This is
Starred by 8.1K users
Forked by 828 users
Languages   TypeScript 80.9% | HTML 9.9% | JavaScript 8.5% | Objective-C 0.3% | CSS 0.2% | Starlark 0.1% | Java 0.1%
🌐
npm
npmjs.com › package › @pdf-lib › fontkit
pdf-lib/fontkit
You can also download @pdf-lib/fontkit as a UMD module from unpkg. The UMD builds have been compiled to ES5, so they should work in any modern browser. UMD builds are useful if you aren't using a package manager or module bundler. For example, you can use them directly in the <script> tag of an HTML page.
      » npm install @pdf-lib/fontkit
    
Published   Nov 28, 2020
Version   1.1.1
Author   Andrew Dillon
🌐
CodeSandbox
codesandbox.io › examples › package › @pdf-lib › fontkit
pdf-lib/fontkit examples
Use this online @pdf-lib/fontkit playground to view and fork @pdf-lib/fontkit example apps and templates on CodeSandbox.
🌐
GitHub
github.com › Hopding › pdf-lib › discussions › 1480
Loading font using fontkit · Hopding/pdf-lib · Discussion #1480
import { PDFDocument } from 'pdf-lib'; import fontKit from '@pdf-lib/fontkit'; import Noto from 'url:./NotoSansJP-Regular.ttf'; // I'm importing a font directly from the project async function main() { const encoder = new TextEncoder(); const ...
Author   Hopding
🌐
npm
npmjs.com › package › @btielen › pdf-lib-fontkit
@btielen/pdf-lib-fontkit - npm
You can also download @pdf-lib/fontkit as a UMD module from unpkg. The UMD builds have been compiled to ES5, so they should work in any modern browser. UMD builds are useful if you aren't using a package manager or module bundler. For example, you can use them directly in the <script> tag of an HTML page.
      » npm install @btielen/pdf-lib-fontkit
    
Published   Feb 04, 2022
Version   1.0.0
Author   Andrew Dillon
🌐
GitHub
github.com › Hopding › pdf-lib › blob › master › src › types › fontkit.ts
pdf-lib/src/types/fontkit.ts at master · Hopding/pdf-lib
* fontkit depending on the font format. They all inherit from the TTFFont class · * and have the same public API. */ export interface Font { // Metadata properties · postscriptName: string | null; fullName: string | null; familyName: string | null; subfamilyName: string | null; copyright: string | null; version: string | null; ·
Author   Hopding
🌐
PDF-LIB
pdf-lib.js.org
PDF-LIB · Create and modify PDF documents in any JavaScript environment.
import { PDFDocument, rgb } from 'pdf-lib' import fontkit from '@pdf-lib/fontkit' async function embedFontAndMeasureText() { const url = 'https://pdf-lib.js.org/assets/ubuntu/Ubuntu-R.ttf' const fontBytes = await fetch(url).then(res => res.arrayBuffer()) const pdfDoc = await PDFDocument.create() pdfDoc.registerFontkit(fontkit) const customFont = await pdfDoc.embedFont(fontBytes) const page = pdfDoc.addPage() const text = 'This is text in an embedded font!' const textSize = 35 const textWidth = customFont.widthOfTextAtSize(text, textSize) const textHeight = customFont.heightAtSize(textSize) page.drawText(text, { x: 40, y: 450, size: textSize, font: customFont, color: rgb(0, 0.53, 0.71), }) page.drawRectangle({ x: 40, y: 450, width: textWidth, height: textHeight, borderColor: rgb(1, 0, 0), borderWidth: 1.5, }) const pdfBytes = await pdfDoc.save() }
🌐
UNPKG
app.unpkg.com › @pdf-lib › [email protected] › files › README.md
UNPKG
* Font subsetting support - create a new font including only the specified glyphs ## Example ```js import fontkit from '@pdf-lib/fontkit'; import fs from 'fs'; // open a font synchronously const fontData = fs.readFileSync('font.ttf'); const font = fontkit.create(fontData); // layout a string, ...
Find elsewhere
🌐
UNPKG
app.unpkg.com › @pdf-lib › [email protected] › files › README.md
pdf-lib/fontkit
* Font subsetting support - create a new font including only the specified glyphs ## Example ```js import fontkit from '@pdf-lib/fontkit'; import fs from 'fs'; // open a font synchronously const fontData = fs.readFileSync('font.ttf'); const font = fontkit.create(fontData); // layout a string, ...
Top answer
1 of 1
1

Most PDF libraries will use a TTF font for PDF mapping "ToUnicode". but there are security restrictions on imbedding binary fonts from external sources into a text based carrier like a PDF wrapper.

PDF-LIB uses a fontkit which needs to do the necessary embedding of pulling a remote untainted binary.ttf into a clients text based HTML editor. So follow the guides for adding more than the font-less 14 Standard Fonts embedded in PDF Viewers / Reader-editors.

Beware as shown above some fonts may not work well without some fettling so for example this Ballet font thinks its Ball et

<html><head><meta charset="utf-8" />
  <script src="https://unpkg.com/[email protected]"></script>
  <script src="https://unpkg.com/@pdf-lib/[email protected]"></script>
  <script src="https://unpkg.com/[email protected]"></script>
    <style>
      body {width: 100vw;height: 100vh;display: flex;justify-content: center;lign-items: center;flex-direction: column;}
      p {font-family: helvetica;font-size: 24px;text-align: center;margin: 25px;}
      .small {font-family: helvetica;font-size: 18px;text-align: center;margin: 25px;}
      button {background-color: #008CBA;border: none;color: white;padding: 15px 32px;text-align: center;font-size: 16px;}
    </style>
</head>
<body>
      <p>Click the button to embed a custom font and measure text drawn in that font with <code>pdf-lib</code></p>
      <button onclick="embedFontAndMeasureText()">Create PDF</button>
      <p class="small">(Your browser will download the resulting file)</p>
</body>

  <script>
    const { PDFDocument, rgb } = PDFLib

    async function embedFontAndMeasureText() {
      const url = 'https://fonts.cdnfonts.com/s/107471/Ballet[opsz].ttf' // Fetch custom font from FULL UNTAINTED URL
      const fontBytes = await fetch(url).then(res => res.arrayBuffer())
      const pdfDoc = await PDFDocument.create() // Create a new PDFDocument
      pdfDoc.registerFontkit(fontkit)  // Register the `fontkit` instance
      const Font15 = await pdfDoc.embedFont(fontBytes)  // Embed custom font in the doc in addition to 14 standard ones

      const page = pdfDoc.addPage()  // Add a blank page to the document

      const text = 'This  is  text  in  remote  embedded  Ballet  font!'  // Create a string of plain text 
      const textSize = 30
      const textWidth = Font15.widthOfTextAtSize(text, textSize) // measure text at size at its custom width and height
      const textHeight = Font15.heightAtSize(textSize)

      // Draw the string of text using Font_15 on the page
      page.drawText(text, {
        x: 40,
        y: 450,
        size: textSize,
        font: Font15,
        color: rgb(0.25, 0.50, 0.75),
      })

      // Draw a box around the string of text
      page.drawRectangle({
        x: 40,
        y: 450,
        width: textWidth,
        height: textHeight,
        borderColor: rgb(1, 0, 0),
        borderWidth: 1.5,
      })

      // Serialize the PDFDocument to bytes (a Uint8Array)
      const pdfBytes = await pdfDoc.save()

            // Trigger the browser to download the PDF document
      download(pdfBytes, "pdf-lib_creation_example.pdf", "application/pdf");
    }
  </script>
</html>
🌐
UNPKG
unpkg.com › browse › @pdf-lib › [email protected] › README.md
pdf-lib/fontkit/README.md
* Font subsetting support - create a new font including only the specified glyphs ## Example ```js import fontkit from '@pdf-lib/fontkit'; import fs from 'fs'; // open a font synchronously const fontData = fs.readFileSync('font.ttf'); const font = fontkit.create(fontData); // layout a string, ...
🌐
Stack Exchange
salesforce.stackexchange.com › questions › 393881 › problem-with-adding-custome-font-and-pdf-lib
lightning web components - problem with adding custome font and pdf-lib - Salesforce Stack Exchange
Examples taken from https://pdf-lib.js.org/ I can't figure out the source of the error and how to fix it · import { loadScript } from "lightning/platformResourceLoader"; import pdflib from "@salesforce/resourceUrl/pdflib"; import fontkit from "@salesforce/resourceUrl/fontkit"; renderedCallback() { loadScript(this, pdflib).then(() => {}); loadScript(this, fontkit).then(() => {}); }
🌐
PDF-LIB
pdf-lib.js.org › docs › api › classes › pdffont
PDFFont · PDF-LIB
Measure the width of a string of text drawn in this font at a given size. For example: const width = font.widthOfTextAtSize('Foo Bar Qux Baz', 36) ... The width of the string of text when drawn in this font at the given size.
🌐
npm
npmjs.com › package › pdf-lib
pdf-lib - npm
Here's a slightly more complicated example demonstrating how to embed a font and measure text in Deno: import { degrees, PDFDocument, rgb, StandardFonts, } from 'https://cdn.skypack.dev/pdf-lib@^1.11.1?dts'; import fontkit from 'https://cdn.skypack.dev/@pdf-lib/fontkit@^1.0.0?dts'; const url = 'https://pdf-lib.js.org/assets/ubuntu/Ubuntu-R.ttf'; const fontBytes = await fetch(url).then((res) => res.arrayBuffer()); const pdfDoc = await PDFDocument.create(); pdfDoc.registerFontkit(fontkit); const customFont = await pdfDoc.embedFont(fontBytes); const page = pdfDoc.addPage(); const text = 'This is
      » npm install pdf-lib
    
Published   Nov 06, 2021
Version   1.17.1
Author   Andrew Dillon
🌐
JSFiddle
jsfiddle.net › Hopding › rgu6ca59 › 2
Embed Font and Measure Text (pdf-lib) - JSFiddle - Code Playground
The Code Completion will now also have the context of all panels before suggesting code to you - so if for example you have some CSS or JS, the HTML panel will suggest code based on the other two panels.
🌐
Wix Studio
forum.wixstudio.com › ask the community
pdf-lib with fontkit won't allow custom fonts - Ask the community - Community Support Forum | Wix Studio
May 23, 2022 - I’m not even calling it directly, it’s being called as part of the embed process. Here’s an example of the relevant code: import { PDFDocument , StandardFonts , TextAlignment } from ‘pdf-lib’ ; var fontkit = require ( ‘@pdf-lib/fontkit’ ); expo...
🌐
UNPKG
unpkg.com › browse › [email protected] › README.md
pdf-lib/README.md
Embedding your own font requires to you load the font data (from a file or via a network request, for example) and pass it to the `embedFont` method. When you embed your own font, you can use any Unicode characters that it supports. This capability frees you from the limitations imposed by the standard fonts. Most PDF files use embedded fonts. You can embed and use a custom font like so ([see also](#embed-font-and-measure-text)): <!-- prettier-ignore --> ```js import { PDFDocument } from 'pdf-lib' import fontkit from '@pdf-lib/fontkit' const url = 'https://pdf-lib.js.org/assets/ubuntu/Ubuntu-R