blob: b72fe362f7aa650d52eaf640d9539592e08b913f [file] [log] [blame]
<h2>ttf-parser in WebAssembly</h2>
<p><small>(supports font files drag and drop)</small></p>
<p><span id="fileName">TTC.ttc</span>:</p>
<p><code>ttfp_fonts_in_collection():</code> <code id="fontsInCollection"></code></p>
<p><code>ttfp_is_variable():</code> <code id="isVariable"></code></p>
<p><code>ttfp_get_weight():</code> <code id="fontWeight"></code></p>
<script>
'use strict';
let wasm;
function update(fontBlob) {
const exports = wasm.instance.exports;
// How our heaped is structured, as ttf-parser doesn't allocate anything
// it is all ours and we can decide how to use it
const heapStart = exports.__heap_base.value;
const fontHandlerAddress = heapStart;
const fontHandlerLength = exports.ttfp_face_size_of();
const fontDataAddress = heapStart + fontHandlerLength;
const fontDataLength = fontBlob.length;
// Copy the fetched blob into WebAssembly machine
const heapu8 = new Uint8Array(exports.memory.buffer);
heapu8.set(fontBlob, fontDataAddress);
fontsInCollection.textContent = exports.ttfp_fonts_in_collection(fontDataAddress, fontDataLength);
// Create font handler
exports.ttfp_face_init(fontDataAddress, fontDataLength, 0/*face index*/, fontHandlerAddress);
isVariable.textContent = exports.ttfp_is_variable(fontHandlerAddress);
fontWeight.textContent = exports.ttfp_get_weight(fontHandlerAddress);
}
fetch('ttfparser.wasm').then(x => x.arrayBuffer()).then(WebAssembly.instantiate).then(result => {
wasm = result;
// Extend wasm machine heap once now that we are here, each page is 64kb
wasm.instance.exports.memory.grow(400);
// Could be done in parallel using Promise.all
fetch('TTC.ttc').then(x => x.arrayBuffer()).then(result => {
update(new Uint8Array(result));
});
});
document.addEventListener('dragover', e => {
e.stopPropagation(); e.preventDefault();
}, false);
document.addEventListener('dragleave', e => {
e.stopPropagation(); e.preventDefault();
}, false);
document.addEventListener('drop', e => {
e.stopPropagation(); e.preventDefault();
handleFontUpdate(e.dataTransfer.files[0]);
});
// document.addEventListener('paste', e => {
// handleFontUpdate(e.clipboardData.files[0]);
// });
function handleFontUpdate(file) {
if (!file) return;
fileName.textContent = file.name;
const reader = new FileReader();
reader.addEventListener('load', () => update(new Uint8Array(reader.result)));
reader.readAsArrayBuffer(file);
}
</script>