Skip to content

Commit

Permalink
Revert "Revert "Revert me: Support shelling out to the hb-subset bina…
Browse files Browse the repository at this point in the history
…ry instead of using the wasm build""

This reverts commit d545459.
  • Loading branch information
papandreou committed Jul 17, 2020
1 parent b2ca5ba commit dcb267d
Showing 1 changed file with 77 additions and 37 deletions.
114 changes: 77 additions & 37 deletions lib/subsetLocalFontWithHarfbuzz.js
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand All @@ -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;
};

0 comments on commit dcb267d

Please sign in to comment.