0

I'm trying to get the very excellent NodeJS PDFKit to use custom fonts OpenSans and Roboto from Google Fonts. My code looks like the following:

this.doc = new PDFDocument({bufferPages: true});
this.doc.registerFont("Roboto-Black", path.join(__dirname, "fonts", "Roboto-Black.ttf"));

I've printed the path - it's finding the right file. I'm getting the following error:

C:\projects\qbdvision\node_modules\restructure\src\VersionedStruct.js:37
        throw new Error("Unknown version " + res.version);
        ^

Error: Unknown version 0
    at VersionedStruct.decode (C:\projects\qbdvision\node_modules\restructure\src\VersionedStruct.js:37:15)
    at C:\projects\qbdvision\node_modules\restructure\src\Pointer.js:69:30
    at Pointer.decode (C:\projects\qbdvision\node_modules\restructure\src\Pointer.js:79:16)
    at ArrayT.decode (C:\projects\qbdvision\node_modules\restructure\src\Array.js:49:30)
    at VersionedStruct.Struct._parseFields (C:\projects\qbdvision\node_modules\restructure\src\Struct.js:53:22)
    at VersionedStruct.decode (C:\projects\qbdvision\node_modules\restructure\src\VersionedStruct.js:42:12)
    at VersionedStruct.decode (C:\projects\qbdvision\node_modules\restructure\src\VersionedStruct.js:40:23)
    at C:\projects\qbdvision\node_modules\restructure\src\Pointer.js:69:30
    at Pointer.decode (C:\projects\qbdvision\node_modules\restructure\src\Pointer.js:79:16)
    at ArrayT.decode (C:\projects\qbdvision\node_modules\restructure\src\Array.js:49:30)
 FAILED

When I removed the Roboto font, and tried the OpenSans one, it worked at least, but everything looked terrible. Letters were bleeding together and looked almost smudged.

I've downloaded the fonts from fonts.google.com by clicking "Select this font", clicking on the "1 Family Selected" popup that comes up and then clicking on the download icon in the upper right hand corner of that popup.

Why won't these fonts work?

Ryan Shillington
  • 23,006
  • 14
  • 93
  • 108

1 Answers1

0

The solution is to convert the fonts into base64 encoding and then import them. So at the command line, using Linux / Cygwin, type:

base64 --wrap=0 Roboto-Black.ttf > Roboto-Black-Base64.ttf

That'll produce a new TTF file that should be all text inside. If you use an external service, make sure there isn't any wrapping. It should be one continuous block of text.

Then, in your NodeJS code, do:

let fs = require("fs");

let doc = new PDFDocument({bufferPages: true});
let filePath = path.join(__dirname, "fonts", "Roboto-Black-Base64.ttf");
let fileContents = fs.readFileSync(filePath, "utf8");
this.doc.registerFont(fontName, new Buffer(fileContents, "base64"));

Then your fonts will show up crystal clear. Props to this answer for giving me the clues I needed.

Ryan Shillington
  • 23,006
  • 14
  • 93
  • 108
  • Actually, I figured out later that I was accidentally running my ttf fonts through a filter which was modifying the encoding of the fonts. Make sure you're not copying the fonts with ant/gradle which has a filter on it meant for your source files only. – Ryan Shillington Apr 04 '18 at 04:05