4

I am building a node-canvas 2d library using paper-jsdom-canvas. PaperJS is failing to use my custom fonts that I am registering using registerFont method of canvas. But when I try to use the canvas project directly, the font is rendered without any problem.

PaperJS project uses 1.3.5 version of node-canvas. I updated the project to use 2.4.1. The only place where it broke, which I fixed was on Canvas.js file line 52.

Changed

impl._canvas = new Canvas(size.width, size.height, type);

to

impl._canvas = Canvas.createCanvas(size.width, size.height, type);

All attributes are working as expected. OS installed fonts are also getting detected. But custom fonts are being ignored.

  registerFont('path-to-font-file', {family: 'CustomFont'});

  const canvas = createCanvas(600, 600);
  const paperCanvas = createCanvas(600, 600);

  const ctx = canvas.getContext('2d');
  ctx.font = "normal 30px CustomFont";
  ctx.fillText("Hello World", 10, 50);

  // using paperjs
  const paper = require("paper");
  const project = new paper.Project(paperCanvas);

  var text = new paper.PointText();
  text.fillColor = 'white';
  text.content = 'HELLO';
  text.fontSize = '60';
  text.fontFamily = 'CustomFont';
  text.strokeWidth = 0;
  text.strokeColor = 'blue';
  text.position = project.view.center;
  text.selected = true;
  project.activeLayer.addChild(text);
  project.view.draw();

  // return canvas.toDataURL(); this canvas renders font correctly.
  return  project.view.element.toDataURL(); // paper does not use registered font

What other change is required to make custom fonts work with PaperJS?

Rashid Shaikh
  • 395
  • 4
  • 12

1 Answers1

2

UPDATE: See this full solution .

There is some kind of timing issue where the font is not loaded before drawing. We just need for the custom fonts to be fully loaded. This can be done with the native new FontFace(..) or a small JS library like FontFaceObserver. You wrap your draw code in font.load().then(..) (or use $.when(f1,f2,f3).done(..) if you have multiple fonts to load).

Simple FontFace working solution: see link above.

FontFaceObserver working JSFiddle: https://jsfiddle.net/3x458h6d/

ORIGINAL POST: Originally I thought that I just had to add an empty/dummy DIV referencing the custom font somewhere above the Canvas. This was suggested here and here. It did help in Firefox, but Chrome/Edge were still not showing the font on startup. I had to use the FontFaceObserver solution above.

<div id="headerPanel">
    Text
    <!-- Note this manual reference to "myCustomFont" used in an unrelated earlier DIV in the HTML,
         in this case on an invisible space -->
    <div style="font-family: myCustomFont">&nbsp;</div>
</div>

<div id="canvasPanel">
    <canvas id="canvas" resize></canvas>
</div>
gene b.
  • 10,512
  • 21
  • 115
  • 227