From dcb267d5e57ca2a6879150e46fe76253eaf54861 Mon Sep 17 00:00:00 2001 From: Andreas Lind Date: Fri, 17 Jul 2020 19:06:30 +0200 Subject: [PATCH] Revert "Revert "Revert me: Support shelling out to the hb-subset binary instead of using the wasm build"" This reverts commit d5454596b878dba9827a2138f66c542277c9a1af. --- lib/subsetLocalFontWithHarfbuzz.js | 114 +++++++++++++++++++---------- 1 file changed, 77 insertions(+), 37 deletions(-) diff --git a/lib/subsetLocalFontWithHarfbuzz.js b/lib/subsetLocalFontWithHarfbuzz.js index e5dbce06..9f5156ae 100644 --- a/lib/subsetLocalFontWithHarfbuzz.js +++ b/lib/subsetLocalFontWithHarfbuzz.js @@ -5,6 +5,10 @@ const _ = require('lodash'); const pathModule = require('path'); const wawoff2 = require('wawoff2'); const woffTool = require('woff2sfnt-sfnt2woff'); +const childProcess = require('child_process'); +const getTemporaryFilePath = require('gettemporaryfilepath'); +const { readFile, writeFile, unlink } = require('fs').promises; +const execFile = require('util').promisify(childProcess.execFile); const loadAndInitializeHarfbuzz = _.once(async () => { const { @@ -30,56 +34,92 @@ module.exports = async (originalFont, targetFormat, text) => { originalFont = await wawoff2.decompress(originalFont); } - const fontBuffer = exports.malloc(originalFont.byteLength); - heapu8.set(new Uint8Array(originalFont), fontBuffer); + let subsetFont; + if (true) { + text = text || '*'; - // Create the face - const blob = exports.hb_blob_create( - fontBuffer, - originalFont.byteLength, - 2, // HB_MEMORY_MODE_WRITABLE - 0, - 0 - ); - const face = exports.hb_face_create(blob, 0); - exports.hb_blob_destroy(blob); + const tempInputFileName = getTemporaryFilePath({ + prefix: 'input-', + suffix: `.ttf`, + }); + const tempOutputFileName = getTemporaryFilePath({ + prefix: 'output-', + suffix: `.ttf`, + }); - // Add glyph indices and subset - const glyphs = exports.hb_set_create(); + const args = [ + `--output-file=${tempOutputFileName}`, + tempInputFileName, + text, + ]; - for (let i = 0; i < text.length; i += 1) { - exports.hb_set_add(glyphs, text.charCodeAt(i)); - } + try { + await writeFile(tempInputFileName, originalFont); + await execFile('../harfbuzz/build/util/hb-subset', args); + // Await to make sure the output file has been consumed before we delete it in the finally block below: + subsetFont = await readFile(tempOutputFileName); + } finally { + unlink(tempInputFileName).then( + () => {}, + () => {} + ); + unlink(tempOutputFileName).then( + () => {}, + () => {} + ); + } + } else { + const fontBuffer = exports.malloc(originalFont.byteLength); + heapu8.set(new Uint8Array(originalFont), fontBuffer); - const input = exports.hb_subset_input_create_or_fail(); - const inputGlyphs = exports.hb_subset_input_unicode_set(input); - exports.hb_set_union(inputGlyphs, glyphs); - const subset = exports.hb_subset(face, input); + // Create the face + const blob = exports.hb_blob_create( + fontBuffer, + originalFont.byteLength, + 2, // HB_MEMORY_MODE_WRITABLE + 0, + 0 + ); + const face = exports.hb_face_create(blob, 0); + exports.hb_blob_destroy(blob); - // Clean up - exports.hb_subset_input_destroy(input); + // Add glyph indices and subset + const glyphs = exports.hb_set_create(); - // Get result blob - const result = exports.hb_face_reference_blob(subset); + for (let i = 0; i < text.length; i += 1) { + exports.hb_set_add(glyphs, text.charCodeAt(i)); + } - const offset = exports.hb_blob_get_data(result, 0); - const subsetFontBlob = heapu8.slice( - offset, - offset + exports.hb_blob_get_length(result) - ); + const input = exports.hb_subset_input_create_or_fail(); + const inputGlyphs = exports.hb_subset_input_unicode_set(input); + exports.hb_set_union(inputGlyphs, glyphs); + const subset = exports.hb_subset(face, input); - // Clean up - exports.hb_blob_destroy(result); - exports.hb_face_destroy(subset); + // Clean up + exports.hb_subset_input_destroy(input); + + // Get result blob + const result = exports.hb_face_reference_blob(subset); + + const offset = exports.hb_blob_get_data(result, 0); + const subsetFontBlob = heapu8.slice( + offset, + offset + exports.hb_blob_get_length(result) + ); + + // Clean up + exports.hb_blob_destroy(result); + exports.hb_face_destroy(subset); + subsetFont = subsetFontBlob; + } - let subsetFont; if (targetFormat === 'woff2') { - subsetFont = Buffer.from(await wawoff2.compress(subsetFontBlob)); + subsetFont = Buffer.from(await wawoff2.compress(subsetFont)); } else if (targetFormat === 'woff') { - subsetFont = woffTool.toWoff(subsetFontBlob); + subsetFont = woffTool.toWoff(subsetFont); } else { // targetFormat === 'truetype' - subsetFont = Buffer.from(subsetFontBlob); + subsetFont = Buffer.from(subsetFont); } return subsetFont; };