question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

page.drawText() inserts spaces when using Thai font

See original GitHub issue

What were you trying to do?

I am trying to use the page.drawText() function to render text in the Thai language

Why were you trying to do this?

To build an application that creates PDF files containing text written in the Thai language

How did you attempt to do it?

The steps I followed are:

  • Download Google Noto Sans Thai font
  • Embed the font in the pdf-lib PDF document
  • Invoke the page.drawText() function passing in the text in Thai

See code example provided in reproduction steps section below.

What actually happened?

The PDF file was successfully created but it seems some large spaces have been inserted into the Thai text in the PDF.

I’ve copied the text from the PDF and pasted below, notice the strange block characters which have been inserted.

แห่งได้เป􏰀ดขึ􏰁นแล้วในการขยายรถไฟใต้ดินลอนดอนครั􏰁งใหญ่ครั􏰁งแรกในศตวรรษนี

Those strange characters appear visually as large blank spaces in the PDF e.g like this:

แห่งได้เป ดขึ นแล้วในการขยายรถไฟใต้ดินลอนดอนครั งใหญ่ครั งแรกในศตวรรษนี

What did you expect to happen?

I expected the Thai text to be rendered as one continuous string without any strange characters or spaces inserted:

แห่งได้เปดขึนแล้วในการขยายรถไฟใต้ดินลอนดอนครังใหญ่ครังแรกในศตวรรษนี

How can we reproduce the issue?

  • Create a Node JS project folder e.g. called ‘pdf-test’
  • cd pdf-test
  • npm init -y
  • npm i pdf-lib
  • npm i @pdf-lib/fontkit
  • Download Noto Sans Thai font from https://fonts.google.com/download?family=Noto Sans Thai
  • Unzip the font and copy the TTF file from Noto_Sans_Thai/static/NotoSansThai/NotoSansThai-Regular.ttf, paste the file into the the project folder pdf-test so it can be loaded by the index.js script below
  • Create a file called index.js and paste the code from below
  • Run the index.js file using the command node index.js which will create the PDF file containing some Thai text
  • Use a PDF viewer/browser e.g. Google Chrome to view the rendered PDF
  • Notice the spacing between some of the Thai text
const fs = require('fs');
const path = require('path');
const { PDFDocument, rgb } = require('pdf-lib');
const fontkit = require('@pdf-lib/fontkit');

(async function run() {

    const pdfDoc = await PDFDocument.create()
    pdfDoc.registerFontkit(fontkit)
    
    // Font downloaded from https://fonts.google.com/download?family=Noto%20Sans%20Thai
    // See also https://fonts.google.com/noto/specimen/Noto+Sans+Thai?query=thai
    const thaiFontBytes = fs.readFileSync(path.join(__dirname, './NotoSansThai-Regular.ttf'))

    const thaiFont = await pdfDoc.embedFont(thaiFontBytes)
    const page = pdfDoc.addPage()
    const { width, height } = page.getSize()

    const fontSize = 11
    page.drawText('แห่งได้เปิดขึ้นแล้วในการขยายรถไฟใต้ดินลอนดอนครั้งใหญ่ครั้งแรกในศตวรรษนี้', {
        x: 50,
        y: height - 2 * fontSize,
        size: fontSize,
        font: thaiFont,
        color: rgb(0, 0.53, 0.71),
    })

    const pdfBytes = await pdfDoc.save()
    fs.writeFile('thai-test.pdf', pdfBytes, () => console.log('PDF file saved.'))
})()

Version

1.16.0

What environment are you running pdf-lib in?

Node

Required Reading

Additional Notes

No response

Issue Analytics

  • State:open
  • Created 2 years ago
  • Reactions:8
  • Comments:9

github_iconTop GitHub Comments

6reactions
MetheeScommented, Nov 12, 2021

(for Thai font) the issue can be resolved when we use .embedFont(fontBytes, { subset: true }); Don’t know why this help.

1reaction
AgileEduLabscommented, Jan 13, 2022

@akomm

same here with helvetica neue roman and helvetica neue condensed It inserts spaces, for example after the sequence of fi, but not after i or f by itself. For example Backoffice becomes Backoffi ce and fifi becomes fi fi

Try the following await pdfDoc.embedFont(YOURFONT, { features: { liga: false }, });

It definitely is a bug and in my opinion is an issue that should be fixed: https://github.com/Hopding/pdf-lib/issues/490

Read more comments on GitHub >

github_iconTop Results From Across the Web

Thai Layout Requirements (Draft) - W3C
This document describes the basic requirements for the Thai language, using the Thai script layout and text support on the Web and in...
Read more >
PDFPage - PDF-LIB - JS.ORG
The options to be used when drawing the SVG path. Returns: void. drawText. ▸ drawText( text : string, options : PDFPageDrawTextOptions): void.
Read more >
Asian Typography - LibreOffice Help
Apply spacing between Asian and non-Asian text. Inserts a space between ideographic and alphabetic text. Related Topics. Enabling Asian language support.
Read more >
Introducing DirectWrite - Win32 apps - Microsoft Learn
This text API can be used in applications that currently use Win32's DrawText to build a modern UI with richly formatted text.
Read more >
Write text on the side of the PDF for every pages
Not sure if it is the "diagonal message" that you are trying to write on all pages but if so, instead of only...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found