Fabric.js: Custom fonts are failing in node (Fabric 1.6.x)

Created on 18 Sep 2016  路  23Comments  路  Source: fabricjs/fabric.js

After updating to 1.6.x (I tried all 1.6 releases) custom fonts are failing in node-canvas.

I did a minimal test case following the instruction from http://fabricjs.com/fabric-intro-part-4

var fs = require('fs'),
    fabric = require('fabric').fabric,
    canvas = fabric.createCanvasForNode(300, 100);

var roboto = new canvas.Font('Roboto', __dirname + '/roboto.ttf');
var robotoSlab = new canvas.Font('Roboto Slab', __dirname + '/roboto-slab.ttf');
canvas.contextContainer.addFont(roboto);
canvas.contextContainer.addFont(robotoSlab);

canvas.add(new fabric.Text('Roboto', {
    left: 10,
    top: 5,
    fontFamily: 'Roboto'
}));

canvas.add(new fabric.Text('Roboto Slab', {
    left: 10,
    top: 50,
    fontFamily: 'Roboto Slab'
}));

var out = fs.createWriteStream(__dirname + '/customfont.png');
var stream = canvas.createPNGStream();
stream.on('data', function(chunk) {
    out.write(chunk);
});

Result in 1.5.0:
customfont1 5 0

Result in 1.6.0 - 1.6.4:
customfont1 6 0

I'm using Node.js v0.12.15 (also tried node 6.5 for Fabric 1.6.4 with the same result).

Download link to fonts: https://fonts.google.com/?selection.family=Roboto|Roboto+Slab

This is possibly a duplicate of #3208, but I created a new issue as I haven't been able to fix it by updating Cairo. The Node-canvas documentation says Cairo 1.8.6 is enough, and I'm using 1.13.0 (Ubuntu 14.04), and also tried 1.14 (Ubuntu Wiley packages), which also works with 1.5.0 but not 1.6.x

Most helpful comment

Thank you both :)

I managed to fix it after reading here https://github.com/Automattic/node-canvas/pull/628. I removed Pango (libpango1.0-dev), deleted node_modules and reinstalled. Maybe this is what you meant @asturur?

So it's actually a known node-canvas issue. More recent versions of Node-canvas are having problems with Pango, and it seems they haven't settled on fixing or disabling Pango since the PR isn't merged. I think this is likely what @Godweed did too, since Pango requires Cairo, and package managers often will remove packages when you remove their dependencies.

I'm not sure this makes the issue "fixed", so I'll leave it open for @asturur to decide.

All 23 comments

@Godweed I think this is the same problem you had. Maybe you know something?

i do not think there are rendering differencies worth mentioning.
We change the way we quote font name but this was in 1.6.4 and if you tried 1.6.x all should change.
In 1.5 we had different node-canvas version i think.
I saw on node-canvas github there is some reference to to using a non cairo version. Did you try it?

@friday At the moment I am running on node 6.5 with the latest fabric 1.6.4 without problem.( I upgraded from node 0.12 and fabric 1.6.0 beta )
Uninstalling fabric, node-canvas, jsdom, condextify and after that install fabric again and it works for me. The problem I guess is jsdom and condextify versions do not upgraded.

Let me know if it solves, i need direction for other answers like that.

Thank you both :)

I managed to fix it after reading here https://github.com/Automattic/node-canvas/pull/628. I removed Pango (libpango1.0-dev), deleted node_modules and reinstalled. Maybe this is what you meant @asturur?

So it's actually a known node-canvas issue. More recent versions of Node-canvas are having problems with Pango, and it seems they haven't settled on fixing or disabling Pango since the PR isn't merged. I think this is likely what @Godweed did too, since Pango requires Cairo, and package managers often will remove packages when you remove their dependencies.

I'm not sure this makes the issue "fixed", so I'll leave it open for @asturur to decide.

I prefer to close it if is a nodejs problem.

Dear future self, @friday 's comment solves the problem where none of the custom fonts are rendering and it is instead using some small font. Removing pango sudo apt-get remove libpango1.0-dev, removing the node_modules, then reinstalling fabric and canvas to also be reinstalled fixes my problem. (Thanks @friday !)

yes sometimes libpango/libcairo makes differences too

Actually, since this PR has been merged with node-canvas now, the issue has been fixed in node-canvas and "sort of" been fixed since fabric 1.7.0. It hasn't been fully fixed since fabric 1.7 uses node-canvas "1.6.x", and it was fixed in 1.6.1. So some installations could still use node-canvas 1.6.0. 1.6.0 works only without libpango, while 1.6.1+ works only with libpango (I just confirmed it with my test case above).

Edit: I misread this completely. The PR is merged upstream but will be released as 2.0

thanks, when i released 1.7.1 nodecanvas was still 1.6.0 and that pr was milestoned as 2.0

I see!
I'm surprised they released it as a patch. Technically it is, but they're requiring libpango again so I thought it would be a major release too.
(which it is)

Just trying to follow along here :) Do I understand this correctly?

node-canvas has a requirement of Cairo. Cairo can utilize pango (libpango) for text layout. If libpango is installed when node-canvas (1.6.2) is built, it causes an issue where my custom fonts don't render and a different font is used. To fix this I uninstalled libpango then deleted my node_modules folder, and reinstalled node-canvas. Now my fonts work again. However, the text layout does a better job when pango is installed. I add text to the canvas that is center aligned. On one line I put several spaces then some more text. Each of those space chars width is wider than it should be (at least wider than it renders in a web browser).

So, a patch was released for node-canvas which utilizes pango again, right? So I can reinstall libpango, remove my node_modules folder again, and reinstall node-canvas (which version includes the patch). And that patch makes it so node-canvas plays well with pango and my fonts will still work and the spacing works well?

Thank you for everyones help on this by the way. I hope to be able to understand this well enough to be able to contribute some day soon!

For what it's worth, my current build:

OS: Ubuntu 14.04
Cairo: 1.13.1 (installed from aptitude)
JpegVersion: 8
gifVersion: 4.1
freetypeversion: 2.5.2
node-canvas: 1.6.2 (installed from npm)
fabricjs: 1.7.1 (installed from npm)
pango: not installed

Current issue is that if I have center aligned text and add a lot of leading spaces then text (think someone signing their name " Sincerely,\n Travis". Then each space char's width is wider than how a web browser renders it.

It seemed when libpango was installed at the time of my node-canvas build, the space char width issue was okay, but my custom fonts didn't work.

Sorry about the confusion! Custom fonts still doesn't work with node-canvas.

I recreated my test incorrectly. It only worked because I installed the wrong package (libpango1.0-0, not libpango1.0-dev). I'm also not at all sure how I read that it was released as 1.6.1. @asturur is right that this is going to be released as 2.0.0

Sorry both of you!

Some clarifications: I don't think Cairo "uses" Pango. Cairo and Pango are two different libraries. Cairo handles graphics and texts. Pango is only for text, and handles it better. Cairo themselves suggest that you don't use their "toy" text api, and use pango instead. https://www.cairographics.org/FAQ/#using_pango

Node-canvas implemented the html5 canvas server rendering with using Cairo, and optionally Pango, if you had it installed when you installed canvas. If you didn't have Pango canvas fallbacks to using Cairo for texts as well, but this will change in node-canvas 2.0.0 and Cairo will be required along with a fix of this issue.

So we'll have to wait for node-canvas 2.0.0.

What's the best approach to this at the moment?

11 days ago node-canvas 2.0.0 requested people to help test their alpha: https://github.com/Automattic/node-canvas/issues/916

I have tried installing it, but haven't been successful implementing it.

My company is doing a web2print shop for stickers and labels. We are using fabric and node, and on our current production server we are running:
node version: 0.10.33
Fabric version: 1.5.0
Canvas version: 1.1.5
libpango: Yes
While this does render custom fonts, the positioning is not precise at all. We're at a point were we have to double check every order, to make sure it's not getting messed up in node, this is obviously very tedious, and we need a fix.

I have also tried:
node version: 6.9.1
Fabric version: 1.7.11
Canvas version: 1.6.5
libpango: Yes
This doesn't throw an error, but it doesn't render the custom font, it uses some default one instead, so not usable for us.

node version: 6.9.1
Fabric version: 1.7.11
Canvas version: 2.0.0-alpha.2
libpango: Yes
result: TypeError: canvas.Font is not a constructor
from var boogalooFont = new canvas.Font('boogaloottf', '/var/www/html/markmaster/public/css/fonts/boogaloo-regular1-webfont.ttf');

What's the current best solution to generate production files from fabric? Where it does render custom fonts, and is not way off on positioning of the text!

So to be honest i have no idea.

I would say in the browser.
I m trying to fix node for fabric since i need in production too, but for now i generate big files in the browser.

I m adding new filters and new svg fixes. as soon as i m done, i freeze the changes and i check node canvas 2.
This may require from 2 weeks to one month since i work just on sundays on fabricjs

Hello all,

I'm experiencing the exact same incorrect result in texts as @friday was. At this point I've spent an endless amount of hours trying to fix it, but the solutions offered in this thread and in countless others I've read unfortunately are not working for me. So I would be very thankful for anyone who is able to make a suggestion for a possible solution!

I'm on CentOS 7 using:

  • canvas-prebuilt: 1.6.5-prerelease.1;
  • fabricjs: 1.7.11.

I'm assigning fonts like this:

var luckiest_guyregular = new canvas.Font('luckiest_guyregular', __dirname+'/fonts/LuckiestGuy.ttf');
canvas.contextContainer.addFont(luckiest_guyregular);

This is a screenshot of a design that I made in the browser:
screen shot 2017-08-10 at 16 32 11

And this is how the PNG looks like after the canvas has been rendered in NodeJS:
id1502375540520_80

As you can see, the font is ignored and the text is a lot smaller than in the design.

Thank you very much in advance for your help!

@me2i: You have to build node-canvas on a system which doesn't have libpango at the time (you can remove it and add it back after building it). Prebuilt won't work unless those were also built on a system without pango (which I very much doubt).

The Cairo fallback is far from perfect though, so if possible generate the png client-side and send to your server.

@friday thank you very much for your time!

So I removed everything of pango with yum remove pango* (there was no package called libpango btw), I ran npm install to install and build the normal node-canvas, I ran my node-server and I'm still getting the error I got before, which made me switch to the prebuilt version of node-canvas in the first place.

So, what it comes down to is when I use the normal node-canvas, I get this error:

Error: ......../node_modules/canvas/build/Release/canvas.node: undefined symbol: _Z22jpeg_resync_to_restartP22jpeg_decompress_structi
    at Error (native)
    at Object.Module._extensions..node (module.js:597:18)
    at Module.load (module.js:487:32)
    at tryModuleLoad (module.js:446:12)
    at Function.Module._load (module.js:438:3)
    at Module.require (module.js:497:17)
    at require (internal/module.js:20:19)
    at Object.<anonymous> .........(./node_modules/canvas/lib/bindings.js:3:18)
    at Module._compile (module.js:570:32)
    at Object.Module._extensions..js (module.js:579:10)

And when I use the prebuilt node-canvas, my texts are rendered incorrectly, just as @friday experienced.

Now I see how this might go a little bit off topic, but does someone maybe has an idea on how to fix this?

Thank you very much in advance!

i belive is a general node canvas issue.

i m personally starting something related with node canvas and i plan to start investigating those issue after the 2.0 release.

i m not good with node-canvas side of fabricjs, so thisay require some time.

i plan to take node canvas 2, in whatever stage it is, since i understood that pango is a requirement now.

I never used yum, but I think it will work if you follow the instructions, but remove the pango-libs: https://github.com/Automattic/node-canvas/wiki/Installation---Fedora

I also think your result looks different from mine, but it could be something with different system fonts/defaults overall. In my experience, the Cairo fallback usually gets the font size right (but not font-weight and margins).

Hi Folks. The last comment here is from 3 months ago. Has there been any updates on this problem since then? Is making huge output in the browser still the only accurate way to generate print output when custom fonts are available? Btw, does this problem exist for SVG output as well? Or just png?

i have still did not find time to go over node.
as soon as i ll do, probably there will be things to fix here and in node canvas.

@semiadam: It hasn't got anything to do with svg/png. The fonts are loaded incorrectly (with pango enabled) or drawn incorrectly (without pango) before node-canvas 2.0, so any output will have the problem, with node.js that is. Render in the browser if possible.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

zhangzhzh picture zhangzhzh  路  4Comments

medialwerk picture medialwerk  路  5Comments

mlev picture mlev  路  3Comments

guettli picture guettli  路  4Comments

urcoder picture urcoder  路  5Comments