Question Details

No question body available.

Tags

javascript html pdf fonts jspdf

Answers (1)

Accepted Answer Available
Accepted Answer
November 30, 2025 Score: 1 Rep: 19,630 Quality: High Completeness: 80%

2025: jspdf doesn't support Open Type features to this date

This is also reported in the github issue section: "Custom font does not get rendered properly in the PDF".

Workaround: try pdfkit.js

Admittedly, unsatisfying to switch the library but perhaps the easiest solution.

pdfkit support Open Type feature settings in text renderings.
You can add them as an object to the text properties like so:


  // write text
  const text = "نگار شکار";
  const [x, y] = [10, 60];

// add your content to the document here, as usual doc.fontSize(100);

// define opentype feaures const features = { features: { liga: true, cswh: true } };

doc.text(text, x, y, features);

Working example

/
  init pdfkit
  and create blob for rendering
 */

(async () => { const doc = new PDFDocument();

// pipe the document to a blob const stream = doc.pipe(blobStream());

// load custom font and register let fontUrl = "https://cdn.jsdelivr.net/npm/@raha.group/persian-fonts@1.0.3/IranNastaliq.regular.ttf";

const font = await fetch(fontUrl); const buffer = await font.arrayBuffer();

doc.registerFont("CustomFont", buffer); doc.font("CustomFont");

// write text const text = "نگار شکار"; const [x, y] = [10, 60];

// add your content to the document here, as usual doc.fontSize(100);

// define opentype feaures const features = { features: { liga: true, cswh: true } };

doc.text(text, x, y, features);

// get a blob when you're done doc.end();

// get objectURL for display or download stream.on("finish", async function() { let blob = stream.toBlob("application/pdf"); let objectURL = await URL.createObjectURL(blob);

// set download link btnDownload.href = objectURL

// render via pdf.js renderPDF(objectURL); }); })();

canvas { border: 1px solid #000 }

Download

// render pdf blob to pdf.js viewer instance async function renderPDF(url) { const canvas = document.getElementById("pdfCanvas"); const ctx = canvas.getContext("2d");

// Load PDF const pdf = await pdfjsLib.getDocument(url).promise;

// Get first page const page = await pdf.getPage(1);

// Prepare viewport const viewport = page.getViewport({ scale: 1.5 }); canvas.width = viewport.width; canvas.height = viewport.height;

// Render await page.render({ canvasContext: ctx, viewport }).promise; }

In the above example I'm rendering the pdf output via pdf.js merely for the sake of illustration (we can't render PDFs in iframes/snippets) – you don't need this for the PDF creating itself.

Emulating substitution features?

Sorry not possible. The main problem: OT Feature substitutions replace certain glyphs (so only the text representation) while the text/string data is unchanged.

To apply substitutions the text shaping engine must support Open Type features. The glyph swapping happens via internal glyph ID mapping – we can't access these in a browser e.g via JS without a full blown font parsing or shaping library.

So there is no way to change the input string to show alternative glyphs as these alternate designs can't be accessed by a unicode point.