question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

noto load/save problem with glyphNames

See original GitHub issue

Hello,

I am trying to work with opentype.js and the noto fonts. The font I use in this example is “NotoSansTagbanwa-Regular.ttf” available in https://noto-website-2.storage.googleapis.com/pkgs/NotoSansTagbanwa-unhinted.zip but the problem also happens with the other noto ttf files.

Basically, the following example outputs an error

var opentype = require('opentype.js');
opentype.load("NotoSansTagbanwa-Regular.ttf", function(err, font) {
  if (err) { console.log(err) }
  else {
    font.toArrayBuffer()
  }
})

leads to

/home/x/tmp/noto/node_modules/opentype.js/src/types.js:75 for (var i = 0; i < v.length; i += 1) { ^ TypeError: Cannot read property ‘length’ of undefined at encode.CHARARRAY (/home/x/tmp/noto/node_modules/opentype.js/src/types.js:75:26) at Object.encode.OBJECT (/home/x/tmp/noto/node_modules/opentype.js/src/types.js:764:12) at Object.encode.INDEX (/home/x/tmp/noto/node_modules/opentype.js/src/types.js:603:24) at sizeOf.INDEX (/home/x/tmp/noto/node_modules/opentype.js/src/types.js:632:19) at Object.sizeOf.TABLE (/home/x/tmp/noto/node_modules/opentype.js/src/types.js:840:21) at Table.sizeOf (/home/x/tmp/noto/node_modules/opentype.js/src/table.js:50:19) at Object.makeCFFTable [as make] (/home/x/tmp/noto/node_modules/opentype.js/src/tables/cff.js:1095:23) at Object.fontToSfntTable [as fontToTable] (/home/x/tmp/noto/node_modules/opentype.js/src/tables/sfnt.js:293:24) at Font.toTables (/home/x/tmp/noto/node_modules/opentype.js/src/font.js:379:17) at Font.toArrayBuffer (/home/x/tmp/noto/node_modules/opentype.js/src/font.js:393:26)

I drilled down on this issue, and it seems to happen because after loading the font, the glyph names are undefined.

The font.glyphNames.names array exists and is empty because post.version = 3

I observed the code path in encoding.js

function addGlyphNames(font) {
    var glyph;
    var glyphIndexMap = font.tables.cmap.glyphIndexMap;
    var charCodes = Object.keys(glyphIndexMap);

    for (var i = 0; i < charCodes.length; i += 1) {
        var c = charCodes[i];
        var glyphIndex = glyphIndexMap[c];
        glyph = font.glyphs.get(glyphIndex);
        glyph.addUnicode(parseInt(c));
    }

    for (i = 0; i < font.glyphs.length; i += 1) {
        glyph = font.glyphs.get(i);
        if (font.cffEncoding) {
            glyph.name = font.cffEncoding.charset[i];
        } else if (font.glyphNames.names) {
            glyph.name = font.glyphNames.glyphIndexToName(i);
        }
    }
}

and we hit glyph.name = font.glyphNames.glyphIndexToName(i); which answers undefined because the array is empty.

then the CHARARRAY crashes because it does not know how to serialize undefined.

I would be happy to propose a PR for this but I don’t know what would be the best spec-friendly fix. I don’t know how to verify if the names exist in the original .ttf, if it is correct or not that a ttf could be created without glyph names, nor if it is acceptable to create a font with empty glyph names

for instance, if the code is modified with

        if (font.cffEncoding) {
            glyph.name = font.cffEncoding.charset[i];
        } else if (font.glyphNames.names && font.glyphNames.names.length) {
            glyph.name = font.glyphNames.glyphIndexToName(i);
        } else {
            glyph.name = '';
        }

then the load/save cycle works but the fix is maybe too spec-preemptive. There seem to be other problems with the load/save cycle of other noto fonts. When I add the patch above and use the test on NotoSans-Regular.ttf I avoid the same problem but then I hit

/home/x/tmp/noto/node_modules/opentype.js/src/check.js:6 throw new Error(message); ^ Error: Unable to write GSUB lookup type 7 tables. at Object.exports.fail (/home/x/tmp/noto/node_modules/opentype.js/src/check.js:6:11) at Object.exports.argument (/home/x/tmp/noto/node_modules/opentype.js/src/check.js:13:17) at /home/x/tmp/noto/node_modules/opentype.js/src/table.js:180:15 at tableList (/home/x/tmp/noto/node_modules/opentype.js/src/table.js:76:68) at new LookupList (/home/x/tmp/noto/node_modules/opentype.js/src/table.js:178:41) at Object.makeGsubTable [as make] (/home/x/tmp/noto/node_modules/opentype.js/src/tables/gsub.js:253:49) at Object.fontToSfntTable [as fontToTable] (/home/x/tmp/noto/node_modules/opentype.js/src/tables/sfnt.js:312:26) at Font.toTables (/home/x/tmp/noto/node_modules/opentype.js/src/font.js:379:17) at Font.toArrayBuffer (/home/x/tmp/noto/node_modules/opentype.js/src/font.js:393:26)

Thanks for your feedback !

Issue Analytics

  • State:closed
  • Created 7 years ago
  • Reactions:1
  • Comments:8 (3 by maintainers)

github_iconTop GitHub Comments

1reaction
littleecommented, Aug 8, 2019

I getting the same error when working with ttf files

TypeError: Cannot read property 'length' of undefined
push../node_modules/opentype.js/src/types.js.encode.CHARARRAY
node_modules/opentype.js/src/types.js:76

  73 | encode.CHARARRAY = function (v) {
  74 |   const b = [];
  75 | 
> 76 |   for (let i = 0; i < v.length; i += 1) {
  77 |     b[i] = v.charCodeAt(i);
  78 |   }
  79 | 
1reaction
jeromewcommented, Nov 12, 2016

Regarding the GSUB type 7 I understood in the code that it is not implemented yet so this is a different problem.

Regarding the glyph names, I saw on https://github.com/fonttools/fonttools that they have the following algorithm:

The glyph names are either extracted from the CFF table or the post table, or are derived from a Unicode cmap table. In the latter case the Adobe Glyph List is used to calculate names based on Unicode values. If all of these methods fail, names are invented based on GlyphID (eg glyph00142)

if this makes sense, we could probably use the same algorithm in opentype.js, the Adobe Glyph List beeing referenced on https://en.wikipedia.org/wiki/Adobe_Glyph_List

Read more comments on GitHub >

github_iconTop Results From Across the Web

Unicode variant selector (u+FE00) not working with Noto Sans ...
Amended answer. With feedback from the comments, the Script= option is enough to activate the variation selectors (which is a glyph, VS1, ...
Read more >
Use Noto fonts - Google Fonts
The Noto Sans fonts are best suitable for short texts, product information, online reading, advertising or branding. For most scripts, the glyphs in...
Read more >
Why isn't there a font that contains all Unicode glyphs?
Why not use multiple fonts and support all unicode that way? Well now, you've just described Adobe's Sans Pro, and Google's Noto (which...
Read more >
mono font windows
Nerd Fonts patches developer targeted fonts with a high number of glyphs (icons). The font is monospaced and I am able to it...
Read more >
Font — PyMuPDF 1.21.1 documentation
A Font object also contains useful general information, like the font bbox, the number of defined glyphs, glyph names or the bbox of...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found