node-pureimage
node-pureimage copied to clipboard
ctx.fillText fails with TypeError: Cannot read property 'getPath' of null
My example code:
const fnt = PImage.registerFont(__dirname + '/../../resources/Roboto-Light.ttf','Source Sans Pro');
fnt.load(() => {
console.log('fnt',fnt);
ctx.font = "32pt 'Source Sans Pro'";
ctx.fillText('foo', 550, 555);
fails with
TypeError: Cannot read property 'getPath' of null
at Object.exports.processTextPath (/project/node_modules/pureimage/src/text.js:62:30)
at Context.fillText (/project/node_modules/pureimage/src/context.js:411:33)
at fnt.load (/project/lib/visualise/render.js:58:11)
at /project/node_modules/pureimage/src/text.js:28:23
at /project/node_modules/opentype.js/src/opentype.js:220:16
at /project/node_modules/opentype.js/src/opentype.js:52:9
at FSReqWrap.readFileAfterClose [as oncomplete] (fs.js:511:3)
+1
Also getting this error. I've built a web API for rapid web development using this as a dependency for a placehold.it replacement.
I've noticed that when calling on this renderer more than once at a time, it's unable to set the font as expected for the callback render function.
@joshmarinacci there seem to be a few issues related to test rendering, typography, font usage etc.
Maybe we should have a label for this? If you're okay with it - I'd be willing to go through the issue tracker and do some housekeeping and closing of issues that can't/won't be fixed, issues that are resolved etc. etc.
I took some time to debug the issue yesterday.
I found a workaround but don't have a fix to commit back just yet.
From what I've found, because the script is already instantiated, it captures a constant true
after the font is loaded. So if you wrap the image creation based on load()
, when you kick off the script every time after that, there's a race time issue. The font doesn't have a chance to load in subsequent requests.
So I found loading the font one time at the beginning of my script, and not reloading it on each request, seems to have fixed the issue.
Any updates on this?
This happens when TEXT.processTextPath is called and font is not loaded completely. Adding a callback to font.load will solve the issue.
Does anyone else maintain it
I've merged the change and all of the tests pass. Can you confirm this fixes the bug for you?
Hi. We also have have a sporadic issue here, because const metrics = exports.measureText(ctx,text)
fails for the exact same reason. font.font
is null
, and hence not yet loaded.
TypeError: Cannot read property 'stringToGlyphs' of null
at Object.exports.measureText (/pureimage/src/text.js:139:29)
at Object.exports.processTextPath (/pureimage/src/text.js:97:29)
at Context.fillText (/pureimage/src/context.js:1114:33)
Any workarounds? Having the stringToGlyphs issue.
Hi @k2xl are you seeing on the console that it prints one of:
if(!font) console.warn("WARNING. Can't find font family ", ctx._font);
if(!font.font) console.warn("WARNING. Can't find font family ", ctx._font);
Hi @joshmarinacci I updated the the latest master branch.
const fontRecord = PImage.registerFont('./lib/fonts/monofonto/monofontorg.otf', 'MyFont', 10, '', '');
fontRecord.loadSync();
context.font = `48px MyFont`;
Error is:
error - TypeError: Cannot read properties of undefined (reading 'length')
Font.stringToGlyphs
.../node_modules/opentype.js/src/font.js (72:27)
Note that on your latest version the registerFont parameters seem to be required (though in the examples in readme it looks like they shouldn't be)
Edit - Also, it looks like registerFont isn't returning a Promise - so I can't use await
On the latest build I'm doing this and it is working.
const fontRecord = pureimage.registerFont('test/unit/fixtures/fonts/SourceSansPro-Regular.ttf', 'MyFont', 10, '', '');
fontRecord.loadSync();
let image = PImage.make(200,200)
let context = image.getContext('2d');
context.font = `48px MyFont`;
const metrics = context.measureText('some text')
The fontRecord.loadSync()
call is definitely working. If I comment it out then the font isn't actually loaded and I get the same error above in stringToGlyphs
.
A few questions:
- Is there any output indicating that your particular font isn't loading?
- Can you send me the exact font you are trying to use (my example code uses the test font in the repo)
- can you send me a small code snippet that completely reproduces the issue?
You are correct that weight and style and variant are required. Technically the CSS spec requires these fields, however they are not currently used. Passing in nulls or undefined should be fine.
The registerFont
function does not return a promise because it is simply registering the font, not actually loading it. Font does have a loadPromise function that you can use like this.
pureimage.registerFont(
'test/unit/fixtures/fonts/SourceSansPro-Regular.ttf', 'MyFont'
).loadPromise().then(()=>{
let image = PImage.make(200,200)
let context = image.getContext('2d');
context.font = `48px MyFont`;
const metrics = context.measureText('some text')
done()
})
Hi, I figured out why it isn't working. In certain situations my code will pass is an empty string to draw with fillText. This seems to error. Handling that check causes the issue to go away. Is the library equipped to handle empty strings / or null strings being passed in? May want to have a check for this and throw an appropriate error.
Currently things are working with one exception - the tests that I wrote can't load the font - since my tests have a different relative directory. This isn't related to your library, but if you have any tips/advice on this definitely appreciated.
Thanks so much for getting back to me on this and getting the npm package updated!
Does passing an empty string still cause a crash? I just added a unit test for it and I can't reproduce the error, but maybe something else fixed it. 🤷