noto load/save problem with glyphNames
See original GitHub issueHello,
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:
- Created 7 years ago
- Reactions:1
- Comments:8 (3 by maintainers)
Top GitHub Comments
I getting the same error when working with ttf files
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