foliojs / fontkit

An advanced font engine for Node and the browser
1.49k stars 221 forks source link

Error while loading custom TTF font #86

Open malyzeli opened 7 years ago

malyzeli commented 7 years ago

Hello,

I'm trying to generate PDF with pdfkit using custom TTF font my friend made, but I'm stuck on error which I don't understand. I spent hours googling and trying to solve it on my own, unfortunately without success. Any help will be appreciated.

The font is made in Corel Draw X6 and in other applications it works - I had success generating PDF from MS Word on Windows and from LibreOffice Writer on Ubuntu Linux - which is why I believe the problem is not in the font file.

I'm building React application using Webpack, where I want to dynamically generate PDF from user input. I tried pdfkit for generating PDF using default font and it works well.

I'm using url-loader to embed font as base64 data url into the application at the compile time.

import fontBase64String from "!url-loader?limit=65536!./fonts/Gammakah.ttf";

Then I decode the string into Buffer on runtime.

const fontBase64Data = /^data:.+;base64,(.*)$/.exec(fontBase64String)[1];
const fontBuffer = Buffer.from(fontBase64Data, "base64");

And then I want to use the font when generating the PDF.

At first I tried this way ...

doc.registerFont("Gammakah", fontBuffer, "Gammakah-Regular");
doc.font("Gammakah");

... which lead me to this error, so I dropped the third argument and this is my last attempt, where I'm stuck now.

doc.registerFont("Gammakah", fontBuffer);
doc.font("Gammakah");

Now I'm getting this error stack - relevant lines highlighted with asterisk.

Uncaught TypeError: Cannot convert undefined or null to object
   *at keys (<anonymous>)
   *at TTFFont.get (index.js:12007)
   *at new EmbeddedFont (embedded.js:24)
   *at Function.Array.concat.PDFFont.open (font.js:25)
   *at PDFDocument.font (fonts.js:39)

    at Application._this.testToPdf (Application.jsx:105)
    at onClick (Application.jsx:173)
    at Object.ReactErrorUtils.invokeGuardedCallback (ReactErrorUtils.js:69)
    at executeDispatch (EventPluginUtils.js:85)
    at Object.executeDispatchesInOrder (EventPluginUtils.js:108)

*get @ index.js:12007
*EmbeddedFont @ embedded.js:24
*Array.concat.PDFFont.open @ font.js:25
*font @ fonts.js:39

Application._this.testToPdf @ Application.jsx:105
onClick @ Application.jsx:173
ReactErrorUtils.invokeGuardedCallback @ ReactErrorUtils.js:69
executeDispatch @ EventPluginUtils.js:85
executeDispatchesInOrder @ EventPluginUtils.js:108
executeDispatchesAndRelease @ EventPluginHub.js:43
executeDispatchesAndReleaseTopLevel @ EventPluginHub.js:54
forEachAccumulated @ forEachAccumulated.js:24
processEventQueue @ EventPluginHub.js:257
runEventQueueInBatch @ ReactEventEmitterMixin.js:17
handleTopLevel @ ReactEventEmitterMixin.js:28
handleTopLevelImpl @ ReactEventListener.js:72
perform @ Transaction.js:140
batchedUpdates @ ReactDefaultBatchingStrategy.js:62
batchedUpdates @ ReactUpdates.js:97
dispatchEvent @ ReactEventListener.js:147

This is the place where the error occurs, on line starting with var lang.

_createClass(TTFFont, [{
  key: 'postscriptName',
  get: function get() {
    var name = this.name.records.postscriptName;
    var lang = _Object$keys(name)[0];
    return name[lang];
  }

Can somebody tell me where is the problem? Or provide me with working code how to embed custom font?

Pomax commented 7 years ago

Is it possible to see the font file, so that it can be run through a few tools like TTX, Font Validator (the new one) and FontForge to see if there's anything that they flag might not be quite correct? (some not-quite-correct fonts can still be loaded by some applications, but the stricter the parser, the more likely they become rejected)