harfbuzz / harfbuzzjs

Providing HarfBuzz shaping library for client/server side JavaScript projects
https://harfbuzz.github.io/harfbuzzjs/
Other
197 stars 34 forks source link

【subset】Vertical glyph layout collapsing in the WebAssembly version Harfbuzz Subset #92

Closed KonghaYao closed 11 months ago

KonghaYao commented 11 months ago

image

subset text ='中文网字计划文网字计划致力于在互联网中提供更加便捷实用的全字符集中文渲染方案中文 网字计划通过精巧设计的字体分包方式将庞大的字体文件切割为多个小型静态分包部署于云端在全网领域内都可快捷稳定地进行加载我们为提高中文字体在网络中的流通体验而努力'

When I used hb_subset.exe to generate the subset, there was no such issue. However, when I used hb_subset.wasm and Node.js to generate the subset, I encountered the problem of collapsing vertical glyph layout.

// Based on https://github.com/harfbuzz/harfbuzzjs/issues/9#issuecomment-507874962
// Which was based on https://github.com/harfbuzz/harfbuzzjs/issues/9#issuecomment-507622485
const { readFile, writeFile } = require('fs').promises;
const { join, extname, basename } = require('path');
const { performance } = require('perf_hooks');

const SUBSET_TEXT = '中文网字计划文网字计划致力于在互联网中提供更加便捷实用的全字符集中文渲染方案中文 网字计划通过精巧设计的字体分包方式将庞大的字体文件切割为多个小型静态分包部署于云端在全网领域内都可快捷稳定地进行加载我们为提高中文字体在网络中的流通体验而努力';
const base = require.resolve('harfbuzzjs');
console.log(base);
(async () => {
    const { instance: { exports } } = await WebAssembly.instantiate(await readFile(join(base, '../hb-subset.wasm')));
    const fileName = 'SmileySans-Oblique.ttf';
    const fontBlob = await readFile(join(__dirname, fileName));

    const t = performance.now();
    const heapu8 = new Uint8Array(exports.memory.buffer);
    const fontBuffer = exports.malloc(fontBlob.byteLength);
    heapu8.set(new Uint8Array(fontBlob), fontBuffer);

    /* Creating a face */
    const blob = exports.hb_blob_create(fontBuffer, fontBlob.byteLength, 2/*HB_MEMORY_MODE_WRITABLE*/, 0, 0);
    const face = exports.hb_face_create(blob, 0);
    exports.hb_blob_destroy(blob);

    /* Add your glyph indices here and subset */
    const input = exports.hb_subset_input_create_or_fail();
    const unicode_set = exports.hb_subset_input_unicode_set(input);
    for (const text of SUBSET_TEXT) {
        exports.hb_set_add(unicode_set, text.codePointAt(0));
    }

    // exports.hb_subset_input_set_drop_hints(input, true);
    const subset = exports.hb_subset_or_fail(face, input);

    /* Clean up */
    exports.hb_subset_input_destroy(input);

    /* Get result blob */
    const resultBlob = exports.hb_face_reference_blob(subset);

    const offset = exports.hb_blob_get_data(resultBlob, 0);
    const subsetByteLength = exports.hb_blob_get_length(resultBlob);
    if (subsetByteLength === 0) {
        exports.hb_blob_destroy(resultBlob);
        exports.hb_face_destroy(subset);
        exports.hb_face_destroy(face);
        exports.free(fontBuffer);
        throw new Error(
            'Failed to create subset font, maybe the input file is corrupted?'
        );
    }

    // Output font data(Uint8Array)
    const subsetFontBlob = heapu8.subarray(offset, offset + exports.hb_blob_get_length(resultBlob));
    console.info('✨ Subset done in', performance.now() - t, 'ms');

    const extName = extname(fileName).toLowerCase();
    const fontName = basename(fileName, extName);
    await writeFile(join(__dirname, '/', `${fontName}.subset${extName}`), subsetFontBlob);    
    console.info(`Wrote subset to: ${__dirname}/${fontName}.subset${extName}`);

    /* Clean up */
    exports.hb_blob_destroy(resultBlob);
    exports.hb_face_destroy(subset);
    exports.hb_face_destroy(face);
    exports.free(fontBuffer);
})();
yisibl commented 11 months ago

Please upload the SmileySans-Oblique.ttf file.

KonghaYao commented 11 months ago

https://github.com/KonghaYao/chinese-free-web-font-storage/tree/fbf01caf8612a6b553cbf73d15dbc95a3cfc1e2c/packages/dyh/fonts @yisibl

KonghaYao commented 11 months ago

image I suspect that either hmtx or some other control for vertical layout has been dropped.

KonghaYao commented 11 months ago

image @yisibl
我添加了#undef HB_NO_VERTICAL 再打包一次 subset.wasm 就解决了这个问题 I added "#undef HB_NO_VERTICAL" and repackaged subset.wasm, which resolved the issue.

yisibl commented 11 months ago

Yes, it looks like this needs to be added to the default configuration. The vertical layout fonts require the correct vmtx table.

image