foliojs / fontkit

An advanced font engine for Node and the browser
1.44k stars 210 forks source link

TypeError when encoding subset of font with set variation #308

Open nk-coding opened 1 year ago

nk-coding commented 1 year ago

When encoding a subset of a font with set variations, I get

TypeError: First argument to DataView constructor must be an ArrayBuffer
    at new DataView (<anonymous>)
    at new $1ed46182c1410e1d$export$9b4f661deaa36c3e (.\node_modules\restructure\dist\main.cjs:111:21)
    at $2784eedf0b35a048$export$2e2bcd8739ae039.encodeSimple (.\node_modules\fontkit\dist\main.cjs:12138:22)
    at $fe042f4b88f46896$export$2e2bcd8739ae039._addGlyph (.\node_modules\fontkit\dist\main.cjs:12179:36)
    at $fe042f4b88f46896$export$2e2bcd8739ae039.encode (.\node_modules\fontkit\dist\main.cjs:12209:43)
    at Object.<anonymous> (.\index.js:23:22)
    at Module._compile (node:internal/modules/cjs/loader:1191:14)
    at Object.Module._extensions..js (node:internal/modules/cjs/loader:1245:10)
    at Module.load (node:internal/modules/cjs/loader:1069:32)
    at Function.Module._load (node:internal/modules/cjs/loader:904:12)

Code to reproduce:

var fontkit = require('fontkit');
var fs = require('fs');

// load file osans.ttf into a buffer synchonously
var buffer = fs.readFileSync('osans.ttf');

// open a font synchronously
var font = fontkit.create(buffer).getVariation({
    wght: 800,
    wdth: 75
});

// layout a string, using default shaping features.
// returns a GlyphRun, describing glyphs and positions.
var run = font.layout('hello world!');

// create a font subset
var subset = font.createSubset();
run.glyphs.forEach(function(glyph) {
  subset.includeGlyph(glyph);
});

let buffer2 = subset.encode();
fs.writeFileSync('subset.ttf', buffer2);

(osans.ttf is the open sans font file obtained from https://fonts.google.com/specimen/Open+Sans)

This is likely due to EncodeStream taking not the length directly, but an Uint8Array (or at least I think so, I'm not completely sure). I think it could be fixed by changing https://github.com/foliojs/fontkit/blob/a5fe0a1834241dbc6eb02beea3b7414c118c5ac9/src/glyph/TTFGlyphEncoder.js#L127 To

let stream = new r.EncodeStream(new Uint8Array(size + tail));

Or something like this