node-pureimage icon indicating copy to clipboard operation
node-pureimage copied to clipboard

ctx.fillText fails with TypeError: Cannot read property 'getPath' of null

Open neophob opened this issue 7 years ago • 13 comments

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)

neophob avatar Jan 24 '18 21:01 neophob

+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.

DigitalKrony avatar Feb 22 '18 22:02 DigitalKrony

@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.

robertmain avatar Feb 23 '18 16:02 robertmain

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.

DigitalKrony avatar Feb 23 '18 16:02 DigitalKrony

Any updates on this?

joshmarinacci avatar Apr 02 '18 00:04 joshmarinacci

This happens when TEXT.processTextPath is called and font is not loaded completely. Adding a callback to font.load will solve the issue.

aqelkp avatar Oct 30 '18 10:10 aqelkp

Does anyone else maintain it

weiyunpeng avatar Feb 16 '20 14:02 weiyunpeng

I've merged the change and all of the tests pass. Can you confirm this fixes the bug for you?

joshmarinacci avatar Feb 29 '20 20:02 joshmarinacci

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)

chemicha avatar Nov 10 '20 16:11 chemicha

Any workarounds? Having the stringToGlyphs issue.

k2xl avatar Jun 01 '22 23:06 k2xl

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);

joshmarinacci avatar Jun 23 '22 21:06 joshmarinacci

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

k2xl avatar Jun 24 '22 17:06 k2xl

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()
        })

joshmarinacci avatar Jun 26 '22 17:06 joshmarinacci

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!

k2xl avatar Jun 26 '22 19:06 k2xl

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. 🤷

joshmarinacci avatar Feb 07 '23 03:02 joshmarinacci