UNPKG

text-to-svg-hb

Version:

Convert text to SVG paths with HarfBuzz support for complex text shaping

688 lines (685 loc) 24.3 kB
var createHarfBuzz = (() => { var _scriptName = typeof document != "undefined" ? document.currentScript?.src : undefined; if (typeof __filename != "undefined") _scriptName = _scriptName || __filename; return async function (moduleArg = {}) { var moduleRtn; var Module = moduleArg; var readyPromiseResolve, readyPromiseReject; var readyPromise = new Promise((resolve, reject) => { readyPromiseResolve = resolve; readyPromiseReject = reject; }); var ENVIRONMENT_IS_WEB = typeof window == "object"; var ENVIRONMENT_IS_WORKER = typeof WorkerGlobalScope != "undefined"; var ENVIRONMENT_IS_NODE = typeof process == "object" && typeof process.versions == "object" && typeof process.versions.node == "string" && process.type != "renderer"; if (ENVIRONMENT_IS_NODE) { } var moduleOverrides = { ...Module }; var arguments_ = []; var thisProgram = "./this.program"; var quit_ = (status, toThrow) => { throw toThrow; }; var scriptDirectory = ""; function locateFile(path) { if (Module["locateFile"]) { return Module["locateFile"](path, scriptDirectory); } return scriptDirectory + path; } var readAsync, readBinary; if (ENVIRONMENT_IS_NODE) { var fs = require("fs"); var nodePath = require("path"); scriptDirectory = __dirname + "/"; readBinary = (filename) => { filename = isFileURI(filename) ? new URL(filename) : filename; var ret = fs.readFileSync(filename); return ret; }; readAsync = async (filename, binary = true) => { filename = isFileURI(filename) ? new URL(filename) : filename; var ret = fs.readFileSync(filename, binary ? undefined : "utf8"); return ret; }; if (!Module["thisProgram"] && process.argv.length > 1) { thisProgram = process.argv[1].replace(/\\/g, "/"); } arguments_ = process.argv.slice(2); quit_ = (status, toThrow) => { process.exitCode = status; throw toThrow; }; } else if (ENVIRONMENT_IS_WEB || ENVIRONMENT_IS_WORKER) { if (ENVIRONMENT_IS_WORKER) { scriptDirectory = self.location.href; } else if (typeof document != "undefined" && document.currentScript) { scriptDirectory = document.currentScript.src; } if (_scriptName) { scriptDirectory = _scriptName; } if (scriptDirectory.startsWith("blob:")) { scriptDirectory = ""; } else { scriptDirectory = scriptDirectory.slice( 0, scriptDirectory.replace(/[?#].*/, "").lastIndexOf("/") + 1, ); } { if (ENVIRONMENT_IS_WORKER) { readBinary = (url) => { var xhr = new XMLHttpRequest(); xhr.open("GET", url, false); xhr.responseType = "arraybuffer"; xhr.send(null); return new Uint8Array(xhr.response); }; } readAsync = async (url) => { if (isFileURI(url)) { return new Promise((resolve, reject) => { var xhr = new XMLHttpRequest(); xhr.open("GET", url, true); xhr.responseType = "arraybuffer"; xhr.onload = () => { if (xhr.status == 200 || (xhr.status == 0 && xhr.response)) { resolve(xhr.response); return; } reject(xhr.status); }; xhr.onerror = reject; xhr.send(null); }); } var response = await fetch(url, { credentials: "same-origin" }); if (response.ok) { return response.arrayBuffer(); } throw new Error(response.status + " : " + response.url); }; } } else { } var out = Module["print"] || console.log.bind(console); var err = Module["printErr"] || console.error.bind(console); Object.assign(Module, moduleOverrides); moduleOverrides = null; if (Module["arguments"]) arguments_ = Module["arguments"]; if (Module["thisProgram"]) thisProgram = Module["thisProgram"]; var wasmBinary = Module["wasmBinary"]; var wasmMemory; var ABORT = false; var EXITSTATUS; var HEAP8, HEAPU8, HEAP16, HEAPU16, HEAP32, HEAPU32, HEAPF32, HEAP64, HEAPU64, HEAPF64; var runtimeInitialized = false; var isFileURI = (filename) => filename.startsWith("file://"); function updateMemoryViews() { var b = wasmMemory.buffer; Module["HEAP8"] = HEAP8 = new Int8Array(b); Module["HEAP16"] = HEAP16 = new Int16Array(b); Module["HEAPU8"] = HEAPU8 = new Uint8Array(b); Module["HEAPU16"] = HEAPU16 = new Uint16Array(b); Module["HEAP32"] = HEAP32 = new Int32Array(b); Module["HEAPU32"] = HEAPU32 = new Uint32Array(b); Module["HEAPF32"] = HEAPF32 = new Float32Array(b); Module["HEAPF64"] = HEAPF64 = new Float64Array(b); Module["HEAP64"] = HEAP64 = new BigInt64Array(b); Module["HEAPU64"] = HEAPU64 = new BigUint64Array(b); } function preRun() { if (Module["preRun"]) { if (typeof Module["preRun"] == "function") Module["preRun"] = [Module["preRun"]]; while (Module["preRun"].length) { addOnPreRun(Module["preRun"].shift()); } } callRuntimeCallbacks(onPreRuns); } function initRuntime() { runtimeInitialized = true; wasmExports["__wasm_call_ctors"](); } function postRun() { if (Module["postRun"]) { if (typeof Module["postRun"] == "function") Module["postRun"] = [Module["postRun"]]; while (Module["postRun"].length) { addOnPostRun(Module["postRun"].shift()); } } callRuntimeCallbacks(onPostRuns); } var runDependencies = 0; var dependenciesFulfilled = null; function addRunDependency(id) { runDependencies++; Module["monitorRunDependencies"]?.(runDependencies); } function removeRunDependency(id) { runDependencies--; Module["monitorRunDependencies"]?.(runDependencies); if (runDependencies == 0) { if (dependenciesFulfilled) { var callback = dependenciesFulfilled; dependenciesFulfilled = null; callback(); } } } function abort(what) { Module["onAbort"]?.(what); what = "Aborted(" + what + ")"; err(what); ABORT = true; what += ". Build with -sASSERTIONS for more info."; var e = new WebAssembly.RuntimeError(what); readyPromiseReject(e); throw e; } var wasmBinaryFile; function findWasmBinary() { return locateFile("hb.wasm"); } function getBinarySync(file) { if (file == wasmBinaryFile && wasmBinary) { return new Uint8Array(wasmBinary); } if (readBinary) { return readBinary(file); } throw "both async and sync fetching of the wasm failed"; } async function getWasmBinary(binaryFile) { if (!wasmBinary) { try { var response = await readAsync(binaryFile); return new Uint8Array(response); } catch {} } return getBinarySync(binaryFile); } async function instantiateArrayBuffer(binaryFile, imports) { try { var binary = await getWasmBinary(binaryFile); var instance = await WebAssembly.instantiate(binary, imports); return instance; } catch (reason) { err(`failed to asynchronously prepare wasm: ${reason}`); abort(reason); } } async function instantiateAsync(binary, binaryFile, imports) { if ( !binary && typeof WebAssembly.instantiateStreaming == "function" && !isFileURI(binaryFile) && !ENVIRONMENT_IS_NODE ) { try { var response = fetch(binaryFile, { credentials: "same-origin" }); var instantiationResult = await WebAssembly.instantiateStreaming( response, imports, ); return instantiationResult; } catch (reason) { err(`wasm streaming compile failed: ${reason}`); err("falling back to ArrayBuffer instantiation"); } } return instantiateArrayBuffer(binaryFile, imports); } function getWasmImports() { return { env: wasmImports, wasi_snapshot_preview1: wasmImports }; } async function createWasm() { function receiveInstance(instance, module) { wasmExports = instance.exports; Module["wasmExports"] = wasmExports; wasmMemory = wasmExports["memory"]; Module["wasmMemory"] = wasmMemory; updateMemoryViews(); wasmTable = wasmExports["__indirect_function_table"]; removeRunDependency("wasm-instantiate"); return wasmExports; } addRunDependency("wasm-instantiate"); function receiveInstantiationResult(result) { return receiveInstance(result["instance"]); } var info = getWasmImports(); if (Module["instantiateWasm"]) { return new Promise((resolve, reject) => { Module["instantiateWasm"](info, (mod, inst) => { receiveInstance(mod, inst); resolve(mod.exports); }); }); } wasmBinaryFile ??= findWasmBinary(); try { var result = await instantiateAsync(wasmBinary, wasmBinaryFile, info); var exports = receiveInstantiationResult(result); return exports; } catch (e) { readyPromiseReject(e); return Promise.reject(e); } } class ExitStatus { name = "ExitStatus"; constructor(status) { this.message = `Program terminated with exit(${status})`; this.status = status; } } var callRuntimeCallbacks = (callbacks) => { while (callbacks.length > 0) { callbacks.shift()(Module); } }; var onPostRuns = []; var addOnPostRun = (cb) => onPostRuns.unshift(cb); var onPreRuns = []; var addOnPreRun = (cb) => onPreRuns.unshift(cb); var noExitRuntime = Module["noExitRuntime"] || true; var __abort_js = () => abort(""); var runtimeKeepaliveCounter = 0; var __emscripten_runtime_keepalive_clear = () => { noExitRuntime = false; runtimeKeepaliveCounter = 0; }; var timers = {}; var handleException = (e) => { if (e instanceof ExitStatus || e == "unwind") { return EXITSTATUS; } quit_(1, e); }; var keepRuntimeAlive = () => noExitRuntime || runtimeKeepaliveCounter > 0; var _proc_exit = (code) => { EXITSTATUS = code; if (!keepRuntimeAlive()) { Module["onExit"]?.(code); ABORT = true; } quit_(code, new ExitStatus(code)); }; var exitJS = (status, implicit) => { EXITSTATUS = status; _proc_exit(status); }; var _exit = exitJS; var maybeExit = () => { if (!keepRuntimeAlive()) { try { _exit(EXITSTATUS); } catch (e) { handleException(e); } } }; var callUserCallback = (func) => { if (ABORT) { return; } try { func(); maybeExit(); } catch (e) { handleException(e); } }; var _emscripten_get_now = () => performance.now(); var __setitimer_js = (which, timeout_ms) => { if (timers[which]) { clearTimeout(timers[which].id); delete timers[which]; } if (!timeout_ms) return 0; var id = setTimeout(() => { delete timers[which]; callUserCallback(() => __emscripten_timeout(which, _emscripten_get_now()), ); }, timeout_ms); timers[which] = { id, timeout_ms }; return 0; }; var getHeapMax = () => 2147483648; var alignMemory = (size, alignment) => Math.ceil(size / alignment) * alignment; var growMemory = (size) => { var b = wasmMemory.buffer; var pages = ((size - b.byteLength + 65535) / 65536) | 0; try { wasmMemory.grow(pages); updateMemoryViews(); return 1; } catch (e) {} }; var _emscripten_resize_heap = (requestedSize) => { var oldSize = HEAPU8.length; requestedSize >>>= 0; var maxHeapSize = getHeapMax(); if (requestedSize > maxHeapSize) { return false; } for (var cutDown = 1; cutDown <= 4; cutDown *= 2) { var overGrownHeapSize = oldSize * (1 + 0.2 / cutDown); overGrownHeapSize = Math.min( overGrownHeapSize, requestedSize + 100663296, ); var newSize = Math.min( maxHeapSize, alignMemory(Math.max(requestedSize, overGrownHeapSize), 65536), ); var replacement = growMemory(newSize); if (replacement) { return true; } } return false; }; var uleb128Encode = (n, target) => { if (n < 128) { target.push(n); } else { target.push(n % 128 | 128, n >> 7); } }; var sigToWasmTypes = (sig) => { var typeNames = { i: "i32", j: "i64", f: "f32", d: "f64", e: "externref", p: "i32", }; var type = { parameters: [], results: sig[0] == "v" ? [] : [typeNames[sig[0]]], }; for (var i = 1; i < sig.length; ++i) { type.parameters.push(typeNames[sig[i]]); } return type; }; var generateFuncType = (sig, target) => { var sigRet = sig.slice(0, 1); var sigParam = sig.slice(1); var typeCodes = { i: 127, p: 127, j: 126, f: 125, d: 124, e: 111 }; target.push(96); uleb128Encode(sigParam.length, target); for (var paramType of sigParam) { target.push(typeCodes[paramType]); } if (sigRet == "v") { target.push(0); } else { target.push(1, typeCodes[sigRet]); } }; var convertJsFunctionToWasm = (func, sig) => { if (typeof WebAssembly.Function == "function") { return new WebAssembly.Function(sigToWasmTypes(sig), func); } var typeSectionBody = [1]; generateFuncType(sig, typeSectionBody); var bytes = [0, 97, 115, 109, 1, 0, 0, 0, 1]; uleb128Encode(typeSectionBody.length, bytes); bytes.push(...typeSectionBody); bytes.push(2, 7, 1, 1, 101, 1, 102, 0, 0, 7, 5, 1, 1, 102, 0, 0); var module = new WebAssembly.Module(new Uint8Array(bytes)); var instance = new WebAssembly.Instance(module, { e: { f: func } }); var wrappedFunc = instance.exports["f"]; return wrappedFunc; }; var wasmTable; var getWasmTableEntry = (funcPtr) => wasmTable.get(funcPtr); var updateTableMap = (offset, count) => { if (functionsInTableMap) { for (var i = offset; i < offset + count; i++) { var item = getWasmTableEntry(i); if (item) { functionsInTableMap.set(item, i); } } } }; var functionsInTableMap; var getFunctionAddress = (func) => { if (!functionsInTableMap) { functionsInTableMap = new WeakMap(); updateTableMap(0, wasmTable.length); } return functionsInTableMap.get(func) || 0; }; var freeTableIndexes = []; var getEmptyTableSlot = () => { if (freeTableIndexes.length) { return freeTableIndexes.pop(); } try { wasmTable.grow(1); } catch (err) { if (!(err instanceof RangeError)) { throw err; } throw "Unable to grow wasm table. Set ALLOW_TABLE_GROWTH."; } return wasmTable.length - 1; }; var setWasmTableEntry = (idx, func) => wasmTable.set(idx, func); var addFunction = (func, sig) => { var rtn = getFunctionAddress(func); if (rtn) { return rtn; } var ret = getEmptyTableSlot(); try { setWasmTableEntry(ret, func); } catch (err) { if (!(err instanceof TypeError)) { throw err; } var wrapped = convertJsFunctionToWasm(func, sig); setWasmTableEntry(ret, wrapped); } functionsInTableMap.set(func, ret); return ret; }; var removeFunction = (index) => { functionsInTableMap.delete(getWasmTableEntry(index)); setWasmTableEntry(index, null); freeTableIndexes.push(index); }; var wasmImports = { _abort_js: __abort_js, _emscripten_runtime_keepalive_clear: __emscripten_runtime_keepalive_clear, _setitimer_js: __setitimer_js, emscripten_resize_heap: _emscripten_resize_heap, proc_exit: _proc_exit, }; var wasmExports = await createWasm(); var ___wasm_call_ctors = wasmExports["__wasm_call_ctors"]; var _hb_blob_create = (Module["_hb_blob_create"] = wasmExports["hb_blob_create"]); var _hb_blob_destroy = (Module["_hb_blob_destroy"] = wasmExports["hb_blob_destroy"]); var _hb_blob_get_length = (Module["_hb_blob_get_length"] = wasmExports["hb_blob_get_length"]); var _hb_blob_get_data = (Module["_hb_blob_get_data"] = wasmExports["hb_blob_get_data"]); var _hb_buffer_serialize_glyphs = (Module["_hb_buffer_serialize_glyphs"] = wasmExports["hb_buffer_serialize_glyphs"]); var _hb_buffer_create = (Module["_hb_buffer_create"] = wasmExports["hb_buffer_create"]); var _hb_buffer_destroy = (Module["_hb_buffer_destroy"] = wasmExports["hb_buffer_destroy"]); var _hb_buffer_get_content_type = (Module["_hb_buffer_get_content_type"] = wasmExports["hb_buffer_get_content_type"]); var _hb_buffer_set_direction = (Module["_hb_buffer_set_direction"] = wasmExports["hb_buffer_set_direction"]); var _hb_buffer_set_script = (Module["_hb_buffer_set_script"] = wasmExports["hb_buffer_set_script"]); var _hb_buffer_set_language = (Module["_hb_buffer_set_language"] = wasmExports["hb_buffer_set_language"]); var _hb_buffer_set_flags = (Module["_hb_buffer_set_flags"] = wasmExports["hb_buffer_set_flags"]); var _hb_buffer_set_cluster_level = (Module["_hb_buffer_set_cluster_level"] = wasmExports["hb_buffer_set_cluster_level"]); var _hb_buffer_get_length = (Module["_hb_buffer_get_length"] = wasmExports["hb_buffer_get_length"]); var _hb_buffer_get_glyph_infos = (Module["_hb_buffer_get_glyph_infos"] = wasmExports["hb_buffer_get_glyph_infos"]); var _hb_buffer_get_glyph_positions = (Module[ "_hb_buffer_get_glyph_positions" ] = wasmExports["hb_buffer_get_glyph_positions"]); var _hb_glyph_info_get_glyph_flags = (Module[ "_hb_glyph_info_get_glyph_flags" ] = wasmExports["hb_glyph_info_get_glyph_flags"]); var _hb_buffer_guess_segment_properties = (Module[ "_hb_buffer_guess_segment_properties" ] = wasmExports["hb_buffer_guess_segment_properties"]); var _hb_buffer_add_utf8 = (Module["_hb_buffer_add_utf8"] = wasmExports["hb_buffer_add_utf8"]); var _hb_buffer_add_utf16 = (Module["_hb_buffer_add_utf16"] = wasmExports["hb_buffer_add_utf16"]); var _hb_buffer_set_message_func = (Module["_hb_buffer_set_message_func"] = wasmExports["hb_buffer_set_message_func"]); var _hb_language_from_string = (Module["_hb_language_from_string"] = wasmExports["hb_language_from_string"]); var _hb_script_from_string = (Module["_hb_script_from_string"] = wasmExports["hb_script_from_string"]); var _hb_version = (Module["_hb_version"] = wasmExports["hb_version"]); var _hb_version_string = (Module["_hb_version_string"] = wasmExports["hb_version_string"]); var _hb_feature_from_string = (Module["_hb_feature_from_string"] = wasmExports["hb_feature_from_string"]); var _malloc = (Module["_malloc"] = wasmExports["malloc"]); var _free = (Module["_free"] = wasmExports["free"]); var _hb_draw_funcs_set_move_to_func = (Module[ "_hb_draw_funcs_set_move_to_func" ] = wasmExports["hb_draw_funcs_set_move_to_func"]); var _hb_draw_funcs_set_line_to_func = (Module[ "_hb_draw_funcs_set_line_to_func" ] = wasmExports["hb_draw_funcs_set_line_to_func"]); var _hb_draw_funcs_set_quadratic_to_func = (Module[ "_hb_draw_funcs_set_quadratic_to_func" ] = wasmExports["hb_draw_funcs_set_quadratic_to_func"]); var _hb_draw_funcs_set_cubic_to_func = (Module[ "_hb_draw_funcs_set_cubic_to_func" ] = wasmExports["hb_draw_funcs_set_cubic_to_func"]); var _hb_draw_funcs_set_close_path_func = (Module[ "_hb_draw_funcs_set_close_path_func" ] = wasmExports["hb_draw_funcs_set_close_path_func"]); var _hb_draw_funcs_create = (Module["_hb_draw_funcs_create"] = wasmExports["hb_draw_funcs_create"]); var _hb_draw_funcs_destroy = (Module["_hb_draw_funcs_destroy"] = wasmExports["hb_draw_funcs_destroy"]); var _hb_face_create = (Module["_hb_face_create"] = wasmExports["hb_face_create"]); var _hb_face_destroy = (Module["_hb_face_destroy"] = wasmExports["hb_face_destroy"]); var _hb_face_reference_table = (Module["_hb_face_reference_table"] = wasmExports["hb_face_reference_table"]); var _hb_face_get_upem = (Module["_hb_face_get_upem"] = wasmExports["hb_face_get_upem"]); var _hb_face_collect_unicodes = (Module["_hb_face_collect_unicodes"] = wasmExports["hb_face_collect_unicodes"]); var _hb_font_draw_glyph = (Module["_hb_font_draw_glyph"] = wasmExports["hb_font_draw_glyph"]); var _hb_font_glyph_to_string = (Module["_hb_font_glyph_to_string"] = wasmExports["hb_font_glyph_to_string"]); var _hb_font_create = (Module["_hb_font_create"] = wasmExports["hb_font_create"]); var _hb_font_destroy = (Module["_hb_font_destroy"] = wasmExports["hb_font_destroy"]); var _hb_font_set_scale = (Module["_hb_font_set_scale"] = wasmExports["hb_font_set_scale"]); var _hb_font_set_variations = (Module["_hb_font_set_variations"] = wasmExports["hb_font_set_variations"]); var _hb_set_create = (Module["_hb_set_create"] = wasmExports["hb_set_create"]); var _hb_set_destroy = (Module["_hb_set_destroy"] = wasmExports["hb_set_destroy"]); var _hb_ot_var_get_axis_infos = (Module["_hb_ot_var_get_axis_infos"] = wasmExports["hb_ot_var_get_axis_infos"]); var _hb_set_get_population = (Module["_hb_set_get_population"] = wasmExports["hb_set_get_population"]); var _hb_set_next_many = (Module["_hb_set_next_many"] = wasmExports["hb_set_next_many"]); var _hb_shape = (Module["_hb_shape"] = wasmExports["hb_shape"]); var __emscripten_timeout = wasmExports["_emscripten_timeout"]; Module["wasmMemory"] = wasmMemory; Module["wasmExports"] = wasmExports; Module["addFunction"] = addFunction; Module["removeFunction"] = removeFunction; function run() { if (runDependencies > 0) { dependenciesFulfilled = run; return; } preRun(); if (runDependencies > 0) { dependenciesFulfilled = run; return; } function doRun() { Module["calledRun"] = true; if (ABORT) return; initRuntime(); readyPromiseResolve(Module); Module["onRuntimeInitialized"]?.(); postRun(); } if (Module["setStatus"]) { Module["setStatus"]("Running..."); setTimeout(() => { setTimeout(() => Module["setStatus"](""), 1); doRun(); }, 1); } else { doRun(); } } if (Module["preInit"]) { if (typeof Module["preInit"] == "function") Module["preInit"] = [Module["preInit"]]; while (Module["preInit"].length > 0) { Module["preInit"].pop()(); } } run(); moduleRtn = readyPromise; return moduleRtn; }; })(); if (typeof exports === "object" && typeof module === "object") { module.exports = createHarfBuzz; // This default export looks redundant, but it allows TS to import this // commonjs style module. module.exports.default = createHarfBuzz; } else if (typeof define === "function" && define["amd"]) define([], () => createHarfBuzz);