harfbuzzjs 0.5.0 → 0.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,3 @@
1
+ {
2
+ "makefile.configureOnOpen": true
3
+ }
package/Makefile ADDED
@@ -0,0 +1,70 @@
1
+ MAKEFLAGS += -s
2
+
3
+ CXX = em++
4
+
5
+ COMMON_CXXFLAGS = \
6
+ -std=c++11 \
7
+ -fno-exceptions \
8
+ -fno-rtti \
9
+ -fno-threadsafe-statics \
10
+ -fvisibility-inlines-hidden \
11
+ -Oz \
12
+ -I. \
13
+ -DHB_TINY \
14
+ -DHB_USE_INTERNAL_QSORT \
15
+ -DHB_EXPERIMENTAL_API
16
+
17
+ HB_CXXFLAGS = \
18
+ $(COMMON_CXXFLAGS) \
19
+ -flto \
20
+ -DHB_CONFIG_OVERRIDE_H=\"config-override.h\"
21
+
22
+ HB_LDFLAGS = \
23
+ --no-entry \
24
+ -s MODULARIZE \
25
+ -s EXPORT_NAME=createHarfBuzz \
26
+ -s EXPORTED_FUNCTIONS=@hb.symbols \
27
+ -s EXPORTED_RUNTIME_METHODS=@em.runtime \
28
+ -s INITIAL_MEMORY=256KB \
29
+ -s ALLOW_MEMORY_GROWTH \
30
+ -s ALLOW_TABLE_GROWTH \
31
+ -lexports.js
32
+
33
+ HB_SRCS = harfbuzz/src/harfbuzz.cc
34
+ HB_DEPS = config-override.h hb.symbols em.runtime
35
+ HB_TARGET = hb.js
36
+
37
+ HB_SUBSET_CXXFLAGS = \
38
+ $(COMMON_CXXFLAGS) \
39
+ -DHB_CONFIG_OVERRIDE_H=\"config-override-subset.h\"
40
+
41
+ HB_SUBSET_LDFLAGS = \
42
+ --no-entry \
43
+ -s EXPORTED_FUNCTIONS=@hb-subset.symbols \
44
+ -s INITIAL_MEMORY=65MB
45
+
46
+ HB_SUBSET_SRCS = harfbuzz/src/harfbuzz-subset.cc
47
+ HB_SUBSET_DEPS = config-override-subset.h hb-subset.symbols
48
+ HB_SUBSET_TARGET = hb-subset.wasm
49
+
50
+ .PHONY: all clean hb hb-subset test
51
+
52
+ all: hb hb-subset
53
+
54
+ hb: $(HB_TARGET)
55
+
56
+ hb-subset: $(HB_SUBSET_TARGET)
57
+
58
+ test: all
59
+ npx mocha test/index.js
60
+
61
+ $(HB_TARGET): $(HB_SRCS) $(HB_DEPS)
62
+ echo " CXX $@"
63
+ $(CXX) $(HB_CXXFLAGS) $(HB_LDFLAGS) -o $@ $(HB_SRCS)
64
+
65
+ $(HB_SUBSET_TARGET): $(HB_SUBSET_SRCS) $(HB_SUBSET_DEPS)
66
+ echo " CXX $@"
67
+ $(CXX) $(HB_SUBSET_CXXFLAGS) $(HB_SUBSET_LDFLAGS) -o $@ $(HB_SUBSET_SRCS)
68
+
69
+ clean:
70
+ rm -f $(HB_TARGET) $(HB_SUBSET_TARGET) hb.wasm
package/README.md CHANGED
@@ -15,12 +15,15 @@ See the demo [here](https://harfbuzz.github.io/harfbuzzjs/).
15
15
 
16
16
  ## Building
17
17
  1. Install emscripten
18
- 2. `./build.sh`
18
+ 2. `make`
19
+
20
+ ## Testing
21
+ 1. `make test`
19
22
 
20
23
  ## Download
21
24
  Download from the [releases tab](https://github.com/harfbuzz/harfbuzzjs/releases).
22
25
 
23
- ## Usage and testing
26
+ ## Usage
24
27
 
25
28
  ### TL;DR
26
29
 
@@ -75,7 +78,7 @@ More examples:
75
78
 
76
79
  1. `(cd examples && node hbjs.example.node.js)`
77
80
 
78
- We provide a tiny wrapper (`hbjs.js`) around the main functionality of harfbuzz, but it's also easy to use other parts. (See `example/nohbjs.js` as an example. However, you may need a custom build to expose additional functionality.)
81
+ We provide a wrapper (`hbjs.js`) around the main functionality of harfbuzz, but it's also easy to use other parts. (See `example/nohbjs.js` as an example. However, you may need a custom build to expose additional functionality.)
79
82
 
80
83
  ## [npm](https://www.npmjs.com/package/harfbuzzjs)
81
84
  Can be added with `npm i harfbuzzjs` or `yarn add harfbuzzjs`, see the examples for
package/em.runtime ADDED
@@ -0,0 +1,13 @@
1
+ addFunction
2
+ removeFunction
3
+ stackAlloc
4
+ stackSave
5
+ stackRestore
6
+ wasmMemory
7
+ wasmExports
8
+ HEAP8
9
+ HEAPU8
10
+ HEAPU16
11
+ HEAP32
12
+ HEAPU32
13
+ HEAPF32
package/hb.js CHANGED
@@ -1,2 +1,2 @@
1
- var createHarfBuzz=(()=>{var _scriptName=typeof document!="undefined"?document.currentScript?.src:undefined;return async function(moduleArg={}){var moduleRtn;var Module=moduleArg;var ENVIRONMENT_IS_WEB=typeof window=="object";var ENVIRONMENT_IS_WORKER=typeof WorkerGlobalScope!="undefined";var ENVIRONMENT_IS_NODE=typeof process=="object"&&process.versions?.node&&process.type!="renderer";var arguments_=[];var thisProgram="./this.program";var quit_=(status,toThrow)=>{throw toThrow};if(typeof __filename!="undefined"){_scriptName=__filename}else if(ENVIRONMENT_IS_WORKER){_scriptName=self.location.href}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");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(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){try{scriptDirectory=new URL(".",_scriptName).href}catch{}{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=console.log.bind(console);var err=console.error.bind(console);var wasmBinary;var ABORT=false;var EXITSTATUS;var isFileURI=filename=>filename.startsWith("file://");var readyPromiseResolve,readyPromiseReject;var wasmMemory;var HEAP8,HEAPU8,HEAP16,HEAPU16,HEAP32,HEAPU32,HEAPF32,HEAPF64;var HEAP64,HEAPU64;var runtimeInitialized=false;function updateMemoryViews(){var b=wasmMemory.buffer;Module["HEAP8"]=HEAP8=new Int8Array(b);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);HEAPF64=new Float64Array(b);HEAP64=new BigInt64Array(b);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&&!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"];assignWasmExports(wasmExports);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)=>{resolve(receiveInstance(mod,inst))})})}wasmBinaryFile??=findWasmBinary();var result=await instantiateAsync(wasmBinary,wasmBinaryFile,info);var exports=receiveInstantiationResult(result);return exports}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.push(cb);var onPreRuns=[];var addOnPreRun=cb=>onPreRuns.push(cb);var 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 oldHeapSize=wasmMemory.buffer.byteLength;var pages=(size-oldHeapSize+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+.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 uleb128EncodeWithLen=arr=>{const n=arr.length;return[n%128|128,n>>7,...arr]};var wasmTypeCodes={i:127,p:127,j:126,f:125,d:124,e:111};var generateTypePack=types=>uleb128EncodeWithLen(Array.from(types,type=>{var code=wasmTypeCodes[type];return code}));var convertJsFunctionToWasm=(func,sig)=>{var bytes=Uint8Array.of(0,97,115,109,1,0,0,0,1,...uleb128EncodeWithLen([1,96,...generateTypePack(sig.slice(1)),...generateTypePack(sig[0]==="v"?"":sig[0])]),2,7,1,1,101,1,102,0,0,7,5,1,1,102,0,0);var module=new WebAssembly.Module(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()}return wasmTable["grow"](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 stackAlloc=sz=>__emscripten_stack_alloc(sz);{if(Module["noExitRuntime"])noExitRuntime=Module["noExitRuntime"];if(Module["print"])out=Module["print"];if(Module["printErr"])err=Module["printErr"];if(Module["wasmBinary"])wasmBinary=Module["wasmBinary"];if(Module["arguments"])arguments_=Module["arguments"];if(Module["thisProgram"])thisProgram=Module["thisProgram"]}Module["wasmMemory"]=wasmMemory;Module["wasmExports"]=wasmExports;Module["stackAlloc"]=stackAlloc;Module["addFunction"]=addFunction;Module["removeFunction"]=removeFunction;var _hb_blob_create,_hb_blob_destroy,_hb_blob_get_length,_hb_blob_get_data,_hb_buffer_serialize_glyphs,_hb_buffer_create,_hb_buffer_destroy,_hb_buffer_get_content_type,_hb_buffer_set_direction,_hb_buffer_set_script,_hb_buffer_set_language,_hb_buffer_set_flags,_hb_buffer_set_cluster_level,_hb_buffer_get_length,_hb_buffer_get_glyph_infos,_hb_buffer_get_glyph_positions,_hb_glyph_info_get_glyph_flags,_hb_buffer_guess_segment_properties,_hb_buffer_add_utf8,_hb_buffer_add_utf16,_hb_buffer_set_message_func,_hb_language_from_string,_hb_language_to_string,_hb_script_from_string,_hb_version,_hb_version_string,_hb_feature_from_string,_malloc,_free,_hb_draw_funcs_set_move_to_func,_hb_draw_funcs_set_line_to_func,_hb_draw_funcs_set_quadratic_to_func,_hb_draw_funcs_set_cubic_to_func,_hb_draw_funcs_set_close_path_func,_hb_draw_funcs_create,_hb_draw_funcs_destroy,_hb_face_create,_hb_face_destroy,_hb_face_reference_table,_hb_face_get_upem,_hb_face_collect_unicodes,_hb_font_funcs_create,_hb_font_funcs_destroy,_hb_font_funcs_set_font_h_extents_func,_hb_font_funcs_set_font_v_extents_func,_hb_font_funcs_set_nominal_glyph_func,_hb_font_funcs_set_nominal_glyphs_func,_hb_font_funcs_set_variation_glyph_func,_hb_font_funcs_set_glyph_h_advance_func,_hb_font_funcs_set_glyph_v_advance_func,_hb_font_funcs_set_glyph_h_advances_func,_hb_font_funcs_set_glyph_v_advances_func,_hb_font_funcs_set_glyph_h_origin_func,_hb_font_funcs_set_glyph_v_origin_func,_hb_font_funcs_set_glyph_h_kerning_func,_hb_font_funcs_set_glyph_extents_func,_hb_font_funcs_set_glyph_name_func,_hb_font_funcs_set_glyph_from_name_func,_hb_font_get_h_extents,_hb_font_get_v_extents,_hb_font_get_glyph_h_advance,_hb_font_get_glyph_v_advance,_hb_font_get_glyph_h_origin,_hb_font_get_glyph_v_origin,_hb_font_get_glyph_extents,_hb_font_get_glyph_from_name,_hb_font_draw_glyph,_hb_font_glyph_to_string,_hb_font_create,_hb_font_set_variations,_hb_font_create_sub_font,_hb_font_reference,_hb_font_destroy,_hb_font_set_funcs,_hb_font_set_scale,_hb_ot_layout_table_get_script_tags,_hb_ot_layout_table_get_feature_tags,_hb_ot_layout_script_get_language_tags,_hb_ot_layout_language_get_feature_tags,_hb_ot_layout_feature_get_name_ids,_hb_ot_name_list_names,_hb_ot_name_get_utf16,_hb_set_create,_hb_set_destroy,_hb_ot_var_get_axis_infos,_hb_set_get_population,_hb_set_next_many,_hb_shape,__emscripten_timeout,__emscripten_stack_alloc;function assignWasmExports(wasmExports){Module["_hb_blob_create"]=_hb_blob_create=wasmExports["hb_blob_create"];Module["_hb_blob_destroy"]=_hb_blob_destroy=wasmExports["hb_blob_destroy"];Module["_hb_blob_get_length"]=_hb_blob_get_length=wasmExports["hb_blob_get_length"];Module["_hb_blob_get_data"]=_hb_blob_get_data=wasmExports["hb_blob_get_data"];Module["_hb_buffer_serialize_glyphs"]=_hb_buffer_serialize_glyphs=wasmExports["hb_buffer_serialize_glyphs"];Module["_hb_buffer_create"]=_hb_buffer_create=wasmExports["hb_buffer_create"];Module["_hb_buffer_destroy"]=_hb_buffer_destroy=wasmExports["hb_buffer_destroy"];Module["_hb_buffer_get_content_type"]=_hb_buffer_get_content_type=wasmExports["hb_buffer_get_content_type"];Module["_hb_buffer_set_direction"]=_hb_buffer_set_direction=wasmExports["hb_buffer_set_direction"];Module["_hb_buffer_set_script"]=_hb_buffer_set_script=wasmExports["hb_buffer_set_script"];Module["_hb_buffer_set_language"]=_hb_buffer_set_language=wasmExports["hb_buffer_set_language"];Module["_hb_buffer_set_flags"]=_hb_buffer_set_flags=wasmExports["hb_buffer_set_flags"];Module["_hb_buffer_set_cluster_level"]=_hb_buffer_set_cluster_level=wasmExports["hb_buffer_set_cluster_level"];Module["_hb_buffer_get_length"]=_hb_buffer_get_length=wasmExports["hb_buffer_get_length"];Module["_hb_buffer_get_glyph_infos"]=_hb_buffer_get_glyph_infos=wasmExports["hb_buffer_get_glyph_infos"];Module["_hb_buffer_get_glyph_positions"]=_hb_buffer_get_glyph_positions=wasmExports["hb_buffer_get_glyph_positions"];Module["_hb_glyph_info_get_glyph_flags"]=_hb_glyph_info_get_glyph_flags=wasmExports["hb_glyph_info_get_glyph_flags"];Module["_hb_buffer_guess_segment_properties"]=_hb_buffer_guess_segment_properties=wasmExports["hb_buffer_guess_segment_properties"];Module["_hb_buffer_add_utf8"]=_hb_buffer_add_utf8=wasmExports["hb_buffer_add_utf8"];Module["_hb_buffer_add_utf16"]=_hb_buffer_add_utf16=wasmExports["hb_buffer_add_utf16"];Module["_hb_buffer_set_message_func"]=_hb_buffer_set_message_func=wasmExports["hb_buffer_set_message_func"];Module["_hb_language_from_string"]=_hb_language_from_string=wasmExports["hb_language_from_string"];Module["_hb_language_to_string"]=_hb_language_to_string=wasmExports["hb_language_to_string"];Module["_hb_script_from_string"]=_hb_script_from_string=wasmExports["hb_script_from_string"];Module["_hb_version"]=_hb_version=wasmExports["hb_version"];Module["_hb_version_string"]=_hb_version_string=wasmExports["hb_version_string"];Module["_hb_feature_from_string"]=_hb_feature_from_string=wasmExports["hb_feature_from_string"];Module["_malloc"]=_malloc=wasmExports["malloc"];Module["_free"]=_free=wasmExports["free"];Module["_hb_draw_funcs_set_move_to_func"]=_hb_draw_funcs_set_move_to_func=wasmExports["hb_draw_funcs_set_move_to_func"];Module["_hb_draw_funcs_set_line_to_func"]=_hb_draw_funcs_set_line_to_func=wasmExports["hb_draw_funcs_set_line_to_func"];Module["_hb_draw_funcs_set_quadratic_to_func"]=_hb_draw_funcs_set_quadratic_to_func=wasmExports["hb_draw_funcs_set_quadratic_to_func"];Module["_hb_draw_funcs_set_cubic_to_func"]=_hb_draw_funcs_set_cubic_to_func=wasmExports["hb_draw_funcs_set_cubic_to_func"];Module["_hb_draw_funcs_set_close_path_func"]=_hb_draw_funcs_set_close_path_func=wasmExports["hb_draw_funcs_set_close_path_func"];Module["_hb_draw_funcs_create"]=_hb_draw_funcs_create=wasmExports["hb_draw_funcs_create"];Module["_hb_draw_funcs_destroy"]=_hb_draw_funcs_destroy=wasmExports["hb_draw_funcs_destroy"];Module["_hb_face_create"]=_hb_face_create=wasmExports["hb_face_create"];Module["_hb_face_destroy"]=_hb_face_destroy=wasmExports["hb_face_destroy"];Module["_hb_face_reference_table"]=_hb_face_reference_table=wasmExports["hb_face_reference_table"];Module["_hb_face_get_upem"]=_hb_face_get_upem=wasmExports["hb_face_get_upem"];Module["_hb_face_collect_unicodes"]=_hb_face_collect_unicodes=wasmExports["hb_face_collect_unicodes"];Module["_hb_font_funcs_create"]=_hb_font_funcs_create=wasmExports["hb_font_funcs_create"];Module["_hb_font_funcs_destroy"]=_hb_font_funcs_destroy=wasmExports["hb_font_funcs_destroy"];Module["_hb_font_funcs_set_font_h_extents_func"]=_hb_font_funcs_set_font_h_extents_func=wasmExports["hb_font_funcs_set_font_h_extents_func"];Module["_hb_font_funcs_set_font_v_extents_func"]=_hb_font_funcs_set_font_v_extents_func=wasmExports["hb_font_funcs_set_font_v_extents_func"];Module["_hb_font_funcs_set_nominal_glyph_func"]=_hb_font_funcs_set_nominal_glyph_func=wasmExports["hb_font_funcs_set_nominal_glyph_func"];Module["_hb_font_funcs_set_nominal_glyphs_func"]=_hb_font_funcs_set_nominal_glyphs_func=wasmExports["hb_font_funcs_set_nominal_glyphs_func"];Module["_hb_font_funcs_set_variation_glyph_func"]=_hb_font_funcs_set_variation_glyph_func=wasmExports["hb_font_funcs_set_variation_glyph_func"];Module["_hb_font_funcs_set_glyph_h_advance_func"]=_hb_font_funcs_set_glyph_h_advance_func=wasmExports["hb_font_funcs_set_glyph_h_advance_func"];Module["_hb_font_funcs_set_glyph_v_advance_func"]=_hb_font_funcs_set_glyph_v_advance_func=wasmExports["hb_font_funcs_set_glyph_v_advance_func"];Module["_hb_font_funcs_set_glyph_h_advances_func"]=_hb_font_funcs_set_glyph_h_advances_func=wasmExports["hb_font_funcs_set_glyph_h_advances_func"];Module["_hb_font_funcs_set_glyph_v_advances_func"]=_hb_font_funcs_set_glyph_v_advances_func=wasmExports["hb_font_funcs_set_glyph_v_advances_func"];Module["_hb_font_funcs_set_glyph_h_origin_func"]=_hb_font_funcs_set_glyph_h_origin_func=wasmExports["hb_font_funcs_set_glyph_h_origin_func"];Module["_hb_font_funcs_set_glyph_v_origin_func"]=_hb_font_funcs_set_glyph_v_origin_func=wasmExports["hb_font_funcs_set_glyph_v_origin_func"];Module["_hb_font_funcs_set_glyph_h_kerning_func"]=_hb_font_funcs_set_glyph_h_kerning_func=wasmExports["hb_font_funcs_set_glyph_h_kerning_func"];Module["_hb_font_funcs_set_glyph_extents_func"]=_hb_font_funcs_set_glyph_extents_func=wasmExports["hb_font_funcs_set_glyph_extents_func"];Module["_hb_font_funcs_set_glyph_name_func"]=_hb_font_funcs_set_glyph_name_func=wasmExports["hb_font_funcs_set_glyph_name_func"];Module["_hb_font_funcs_set_glyph_from_name_func"]=_hb_font_funcs_set_glyph_from_name_func=wasmExports["hb_font_funcs_set_glyph_from_name_func"];Module["_hb_font_get_h_extents"]=_hb_font_get_h_extents=wasmExports["hb_font_get_h_extents"];Module["_hb_font_get_v_extents"]=_hb_font_get_v_extents=wasmExports["hb_font_get_v_extents"];Module["_hb_font_get_glyph_h_advance"]=_hb_font_get_glyph_h_advance=wasmExports["hb_font_get_glyph_h_advance"];Module["_hb_font_get_glyph_v_advance"]=_hb_font_get_glyph_v_advance=wasmExports["hb_font_get_glyph_v_advance"];Module["_hb_font_get_glyph_h_origin"]=_hb_font_get_glyph_h_origin=wasmExports["hb_font_get_glyph_h_origin"];Module["_hb_font_get_glyph_v_origin"]=_hb_font_get_glyph_v_origin=wasmExports["hb_font_get_glyph_v_origin"];Module["_hb_font_get_glyph_extents"]=_hb_font_get_glyph_extents=wasmExports["hb_font_get_glyph_extents"];Module["_hb_font_get_glyph_from_name"]=_hb_font_get_glyph_from_name=wasmExports["hb_font_get_glyph_from_name"];Module["_hb_font_draw_glyph"]=_hb_font_draw_glyph=wasmExports["hb_font_draw_glyph"];Module["_hb_font_glyph_to_string"]=_hb_font_glyph_to_string=wasmExports["hb_font_glyph_to_string"];Module["_hb_font_create"]=_hb_font_create=wasmExports["hb_font_create"];Module["_hb_font_set_variations"]=_hb_font_set_variations=wasmExports["hb_font_set_variations"];Module["_hb_font_create_sub_font"]=_hb_font_create_sub_font=wasmExports["hb_font_create_sub_font"];Module["_hb_font_reference"]=_hb_font_reference=wasmExports["hb_font_reference"];Module["_hb_font_destroy"]=_hb_font_destroy=wasmExports["hb_font_destroy"];Module["_hb_font_set_funcs"]=_hb_font_set_funcs=wasmExports["hb_font_set_funcs"];Module["_hb_font_set_scale"]=_hb_font_set_scale=wasmExports["hb_font_set_scale"];Module["_hb_ot_layout_table_get_script_tags"]=_hb_ot_layout_table_get_script_tags=wasmExports["hb_ot_layout_table_get_script_tags"];Module["_hb_ot_layout_table_get_feature_tags"]=_hb_ot_layout_table_get_feature_tags=wasmExports["hb_ot_layout_table_get_feature_tags"];Module["_hb_ot_layout_script_get_language_tags"]=_hb_ot_layout_script_get_language_tags=wasmExports["hb_ot_layout_script_get_language_tags"];Module["_hb_ot_layout_language_get_feature_tags"]=_hb_ot_layout_language_get_feature_tags=wasmExports["hb_ot_layout_language_get_feature_tags"];Module["_hb_ot_layout_feature_get_name_ids"]=_hb_ot_layout_feature_get_name_ids=wasmExports["hb_ot_layout_feature_get_name_ids"];Module["_hb_ot_name_list_names"]=_hb_ot_name_list_names=wasmExports["hb_ot_name_list_names"];Module["_hb_ot_name_get_utf16"]=_hb_ot_name_get_utf16=wasmExports["hb_ot_name_get_utf16"];Module["_hb_set_create"]=_hb_set_create=wasmExports["hb_set_create"];Module["_hb_set_destroy"]=_hb_set_destroy=wasmExports["hb_set_destroy"];Module["_hb_ot_var_get_axis_infos"]=_hb_ot_var_get_axis_infos=wasmExports["hb_ot_var_get_axis_infos"];Module["_hb_set_get_population"]=_hb_set_get_population=wasmExports["hb_set_get_population"];Module["_hb_set_next_many"]=_hb_set_next_many=wasmExports["hb_set_next_many"];Module["_hb_shape"]=_hb_shape=wasmExports["hb_shape"];__emscripten_timeout=wasmExports["_emscripten_timeout"];__emscripten_stack_alloc=wasmExports["_emscripten_stack_alloc"]}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();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()}}function preInit(){if(Module["preInit"]){if(typeof Module["preInit"]=="function")Module["preInit"]=[Module["preInit"]];while(Module["preInit"].length>0){Module["preInit"].shift()()}}}preInit();run();if(runtimeInitialized){moduleRtn=Module}else{moduleRtn=new Promise((resolve,reject)=>{readyPromiseResolve=resolve;readyPromiseReject=reject})}
1
+ var createHarfBuzz=(()=>{var _scriptName=typeof document!="undefined"?document.currentScript?.src:undefined;return async function(moduleArg={}){var moduleRtn;var Module=moduleArg;var ENVIRONMENT_IS_WEB=typeof window=="object";var ENVIRONMENT_IS_WORKER=typeof WorkerGlobalScope!="undefined";var ENVIRONMENT_IS_NODE=typeof process=="object"&&process.versions?.node&&process.type!="renderer";var arguments_=[];var thisProgram="./this.program";var quit_=(status,toThrow)=>{throw toThrow};if(typeof __filename!="undefined"){_scriptName=__filename}else if(ENVIRONMENT_IS_WORKER){_scriptName=self.location.href}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");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(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){try{scriptDirectory=new URL(".",_scriptName).href}catch{}{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=console.log.bind(console);var err=console.error.bind(console);var wasmBinary;var ABORT=false;var EXITSTATUS;var isFileURI=filename=>filename.startsWith("file://");var readyPromiseResolve,readyPromiseReject;var wasmMemory;var HEAP8,HEAPU8,HEAP16,HEAPU16,HEAP32,HEAPU32,HEAPF32,HEAPF64;var HEAP64,HEAPU64;var runtimeInitialized=false;function updateMemoryViews(){var b=wasmMemory.buffer;Module["HEAP8"]=HEAP8=new Int8Array(b);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);HEAPF64=new Float64Array(b);HEAP64=new BigInt64Array(b);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&&!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"];assignWasmExports(wasmExports);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)=>{resolve(receiveInstance(mod,inst))})})}wasmBinaryFile??=findWasmBinary();var result=await instantiateAsync(wasmBinary,wasmBinaryFile,info);var exports=receiveInstantiationResult(result);return exports}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.push(cb);var onPreRuns=[];var addOnPreRun=cb=>onPreRuns.push(cb);var noExitRuntime=true;var stackRestore=val=>__emscripten_stack_restore(val);var stackSave=()=>_emscripten_stack_get_current();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 oldHeapSize=wasmMemory.buffer.byteLength;var pages=(size-oldHeapSize+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+.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 uleb128EncodeWithLen=arr=>{const n=arr.length;return[n%128|128,n>>7,...arr]};var wasmTypeCodes={i:127,p:127,j:126,f:125,d:124,e:111};var generateTypePack=types=>uleb128EncodeWithLen(Array.from(types,type=>{var code=wasmTypeCodes[type];return code}));var convertJsFunctionToWasm=(func,sig)=>{var bytes=Uint8Array.of(0,97,115,109,1,0,0,0,1,...uleb128EncodeWithLen([1,96,...generateTypePack(sig.slice(1)),...generateTypePack(sig[0]==="v"?"":sig[0])]),2,7,1,1,101,1,102,0,0,7,5,1,1,102,0,0);var module=new WebAssembly.Module(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()}return wasmTable["grow"](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 stackAlloc=sz=>__emscripten_stack_alloc(sz);{if(Module["noExitRuntime"])noExitRuntime=Module["noExitRuntime"];if(Module["print"])out=Module["print"];if(Module["printErr"])err=Module["printErr"];if(Module["wasmBinary"])wasmBinary=Module["wasmBinary"];if(Module["arguments"])arguments_=Module["arguments"];if(Module["thisProgram"])thisProgram=Module["thisProgram"]}Module["wasmMemory"]=wasmMemory;Module["wasmExports"]=wasmExports;Module["stackSave"]=stackSave;Module["stackRestore"]=stackRestore;Module["stackAlloc"]=stackAlloc;Module["addFunction"]=addFunction;Module["removeFunction"]=removeFunction;var _hb_blob_create,_hb_blob_destroy,_hb_blob_get_length,_hb_blob_get_data,_hb_buffer_serialize_glyphs,_hb_buffer_create,_hb_buffer_destroy,_hb_buffer_get_content_type,_hb_buffer_set_direction,_hb_buffer_set_script,_hb_buffer_set_language,_hb_buffer_set_flags,_hb_buffer_set_cluster_level,_hb_buffer_get_length,_hb_buffer_get_glyph_infos,_hb_buffer_get_glyph_positions,_hb_glyph_info_get_glyph_flags,_hb_buffer_guess_segment_properties,_hb_buffer_add_utf8,_hb_buffer_add_utf16,_hb_buffer_add_codepoints,_hb_buffer_set_message_func,_hb_language_from_string,_hb_language_to_string,_hb_script_from_string,_hb_version,_hb_version_string,_hb_feature_from_string,_malloc,_free,_hb_draw_funcs_set_move_to_func,_hb_draw_funcs_set_line_to_func,_hb_draw_funcs_set_quadratic_to_func,_hb_draw_funcs_set_cubic_to_func,_hb_draw_funcs_set_close_path_func,_hb_draw_funcs_create,_hb_draw_funcs_destroy,_hb_face_create,_hb_face_destroy,_hb_face_reference_table,_hb_face_get_upem,_hb_face_collect_unicodes,_hb_font_funcs_create,_hb_font_funcs_destroy,_hb_font_funcs_set_font_h_extents_func,_hb_font_funcs_set_font_v_extents_func,_hb_font_funcs_set_nominal_glyph_func,_hb_font_funcs_set_nominal_glyphs_func,_hb_font_funcs_set_variation_glyph_func,_hb_font_funcs_set_glyph_h_advance_func,_hb_font_funcs_set_glyph_v_advance_func,_hb_font_funcs_set_glyph_h_advances_func,_hb_font_funcs_set_glyph_v_advances_func,_hb_font_funcs_set_glyph_h_origin_func,_hb_font_funcs_set_glyph_v_origin_func,_hb_font_funcs_set_glyph_h_kerning_func,_hb_font_funcs_set_glyph_extents_func,_hb_font_funcs_set_glyph_name_func,_hb_font_funcs_set_glyph_from_name_func,_hb_font_get_h_extents,_hb_font_get_v_extents,_hb_font_get_glyph_h_advance,_hb_font_get_glyph_v_advance,_hb_font_get_glyph_h_origin,_hb_font_get_glyph_v_origin,_hb_font_get_glyph_extents,_hb_font_get_glyph_from_name,_hb_font_draw_glyph,_hb_font_glyph_to_string,_hb_font_create,_hb_font_set_variations,_hb_font_create_sub_font,_hb_font_reference,_hb_font_destroy,_hb_font_set_funcs,_hb_font_set_scale,_hb_ot_layout_table_get_script_tags,_hb_ot_layout_table_get_feature_tags,_hb_ot_layout_script_get_language_tags,_hb_ot_layout_language_get_feature_tags,_hb_ot_layout_feature_get_name_ids,_hb_ot_name_list_names,_hb_ot_name_get_utf16,_hb_set_create,_hb_set_destroy,_hb_ot_tag_to_script,_hb_ot_tag_to_language,_hb_ot_var_get_axis_infos,_hb_set_get_population,_hb_set_next_many,_hb_shape,__emscripten_timeout,__emscripten_stack_restore,__emscripten_stack_alloc,_emscripten_stack_get_current;function assignWasmExports(wasmExports){Module["_hb_blob_create"]=_hb_blob_create=wasmExports["hb_blob_create"];Module["_hb_blob_destroy"]=_hb_blob_destroy=wasmExports["hb_blob_destroy"];Module["_hb_blob_get_length"]=_hb_blob_get_length=wasmExports["hb_blob_get_length"];Module["_hb_blob_get_data"]=_hb_blob_get_data=wasmExports["hb_blob_get_data"];Module["_hb_buffer_serialize_glyphs"]=_hb_buffer_serialize_glyphs=wasmExports["hb_buffer_serialize_glyphs"];Module["_hb_buffer_create"]=_hb_buffer_create=wasmExports["hb_buffer_create"];Module["_hb_buffer_destroy"]=_hb_buffer_destroy=wasmExports["hb_buffer_destroy"];Module["_hb_buffer_get_content_type"]=_hb_buffer_get_content_type=wasmExports["hb_buffer_get_content_type"];Module["_hb_buffer_set_direction"]=_hb_buffer_set_direction=wasmExports["hb_buffer_set_direction"];Module["_hb_buffer_set_script"]=_hb_buffer_set_script=wasmExports["hb_buffer_set_script"];Module["_hb_buffer_set_language"]=_hb_buffer_set_language=wasmExports["hb_buffer_set_language"];Module["_hb_buffer_set_flags"]=_hb_buffer_set_flags=wasmExports["hb_buffer_set_flags"];Module["_hb_buffer_set_cluster_level"]=_hb_buffer_set_cluster_level=wasmExports["hb_buffer_set_cluster_level"];Module["_hb_buffer_get_length"]=_hb_buffer_get_length=wasmExports["hb_buffer_get_length"];Module["_hb_buffer_get_glyph_infos"]=_hb_buffer_get_glyph_infos=wasmExports["hb_buffer_get_glyph_infos"];Module["_hb_buffer_get_glyph_positions"]=_hb_buffer_get_glyph_positions=wasmExports["hb_buffer_get_glyph_positions"];Module["_hb_glyph_info_get_glyph_flags"]=_hb_glyph_info_get_glyph_flags=wasmExports["hb_glyph_info_get_glyph_flags"];Module["_hb_buffer_guess_segment_properties"]=_hb_buffer_guess_segment_properties=wasmExports["hb_buffer_guess_segment_properties"];Module["_hb_buffer_add_utf8"]=_hb_buffer_add_utf8=wasmExports["hb_buffer_add_utf8"];Module["_hb_buffer_add_utf16"]=_hb_buffer_add_utf16=wasmExports["hb_buffer_add_utf16"];Module["_hb_buffer_add_codepoints"]=_hb_buffer_add_codepoints=wasmExports["hb_buffer_add_codepoints"];Module["_hb_buffer_set_message_func"]=_hb_buffer_set_message_func=wasmExports["hb_buffer_set_message_func"];Module["_hb_language_from_string"]=_hb_language_from_string=wasmExports["hb_language_from_string"];Module["_hb_language_to_string"]=_hb_language_to_string=wasmExports["hb_language_to_string"];Module["_hb_script_from_string"]=_hb_script_from_string=wasmExports["hb_script_from_string"];Module["_hb_version"]=_hb_version=wasmExports["hb_version"];Module["_hb_version_string"]=_hb_version_string=wasmExports["hb_version_string"];Module["_hb_feature_from_string"]=_hb_feature_from_string=wasmExports["hb_feature_from_string"];Module["_malloc"]=_malloc=wasmExports["malloc"];Module["_free"]=_free=wasmExports["free"];Module["_hb_draw_funcs_set_move_to_func"]=_hb_draw_funcs_set_move_to_func=wasmExports["hb_draw_funcs_set_move_to_func"];Module["_hb_draw_funcs_set_line_to_func"]=_hb_draw_funcs_set_line_to_func=wasmExports["hb_draw_funcs_set_line_to_func"];Module["_hb_draw_funcs_set_quadratic_to_func"]=_hb_draw_funcs_set_quadratic_to_func=wasmExports["hb_draw_funcs_set_quadratic_to_func"];Module["_hb_draw_funcs_set_cubic_to_func"]=_hb_draw_funcs_set_cubic_to_func=wasmExports["hb_draw_funcs_set_cubic_to_func"];Module["_hb_draw_funcs_set_close_path_func"]=_hb_draw_funcs_set_close_path_func=wasmExports["hb_draw_funcs_set_close_path_func"];Module["_hb_draw_funcs_create"]=_hb_draw_funcs_create=wasmExports["hb_draw_funcs_create"];Module["_hb_draw_funcs_destroy"]=_hb_draw_funcs_destroy=wasmExports["hb_draw_funcs_destroy"];Module["_hb_face_create"]=_hb_face_create=wasmExports["hb_face_create"];Module["_hb_face_destroy"]=_hb_face_destroy=wasmExports["hb_face_destroy"];Module["_hb_face_reference_table"]=_hb_face_reference_table=wasmExports["hb_face_reference_table"];Module["_hb_face_get_upem"]=_hb_face_get_upem=wasmExports["hb_face_get_upem"];Module["_hb_face_collect_unicodes"]=_hb_face_collect_unicodes=wasmExports["hb_face_collect_unicodes"];Module["_hb_font_funcs_create"]=_hb_font_funcs_create=wasmExports["hb_font_funcs_create"];Module["_hb_font_funcs_destroy"]=_hb_font_funcs_destroy=wasmExports["hb_font_funcs_destroy"];Module["_hb_font_funcs_set_font_h_extents_func"]=_hb_font_funcs_set_font_h_extents_func=wasmExports["hb_font_funcs_set_font_h_extents_func"];Module["_hb_font_funcs_set_font_v_extents_func"]=_hb_font_funcs_set_font_v_extents_func=wasmExports["hb_font_funcs_set_font_v_extents_func"];Module["_hb_font_funcs_set_nominal_glyph_func"]=_hb_font_funcs_set_nominal_glyph_func=wasmExports["hb_font_funcs_set_nominal_glyph_func"];Module["_hb_font_funcs_set_nominal_glyphs_func"]=_hb_font_funcs_set_nominal_glyphs_func=wasmExports["hb_font_funcs_set_nominal_glyphs_func"];Module["_hb_font_funcs_set_variation_glyph_func"]=_hb_font_funcs_set_variation_glyph_func=wasmExports["hb_font_funcs_set_variation_glyph_func"];Module["_hb_font_funcs_set_glyph_h_advance_func"]=_hb_font_funcs_set_glyph_h_advance_func=wasmExports["hb_font_funcs_set_glyph_h_advance_func"];Module["_hb_font_funcs_set_glyph_v_advance_func"]=_hb_font_funcs_set_glyph_v_advance_func=wasmExports["hb_font_funcs_set_glyph_v_advance_func"];Module["_hb_font_funcs_set_glyph_h_advances_func"]=_hb_font_funcs_set_glyph_h_advances_func=wasmExports["hb_font_funcs_set_glyph_h_advances_func"];Module["_hb_font_funcs_set_glyph_v_advances_func"]=_hb_font_funcs_set_glyph_v_advances_func=wasmExports["hb_font_funcs_set_glyph_v_advances_func"];Module["_hb_font_funcs_set_glyph_h_origin_func"]=_hb_font_funcs_set_glyph_h_origin_func=wasmExports["hb_font_funcs_set_glyph_h_origin_func"];Module["_hb_font_funcs_set_glyph_v_origin_func"]=_hb_font_funcs_set_glyph_v_origin_func=wasmExports["hb_font_funcs_set_glyph_v_origin_func"];Module["_hb_font_funcs_set_glyph_h_kerning_func"]=_hb_font_funcs_set_glyph_h_kerning_func=wasmExports["hb_font_funcs_set_glyph_h_kerning_func"];Module["_hb_font_funcs_set_glyph_extents_func"]=_hb_font_funcs_set_glyph_extents_func=wasmExports["hb_font_funcs_set_glyph_extents_func"];Module["_hb_font_funcs_set_glyph_name_func"]=_hb_font_funcs_set_glyph_name_func=wasmExports["hb_font_funcs_set_glyph_name_func"];Module["_hb_font_funcs_set_glyph_from_name_func"]=_hb_font_funcs_set_glyph_from_name_func=wasmExports["hb_font_funcs_set_glyph_from_name_func"];Module["_hb_font_get_h_extents"]=_hb_font_get_h_extents=wasmExports["hb_font_get_h_extents"];Module["_hb_font_get_v_extents"]=_hb_font_get_v_extents=wasmExports["hb_font_get_v_extents"];Module["_hb_font_get_glyph_h_advance"]=_hb_font_get_glyph_h_advance=wasmExports["hb_font_get_glyph_h_advance"];Module["_hb_font_get_glyph_v_advance"]=_hb_font_get_glyph_v_advance=wasmExports["hb_font_get_glyph_v_advance"];Module["_hb_font_get_glyph_h_origin"]=_hb_font_get_glyph_h_origin=wasmExports["hb_font_get_glyph_h_origin"];Module["_hb_font_get_glyph_v_origin"]=_hb_font_get_glyph_v_origin=wasmExports["hb_font_get_glyph_v_origin"];Module["_hb_font_get_glyph_extents"]=_hb_font_get_glyph_extents=wasmExports["hb_font_get_glyph_extents"];Module["_hb_font_get_glyph_from_name"]=_hb_font_get_glyph_from_name=wasmExports["hb_font_get_glyph_from_name"];Module["_hb_font_draw_glyph"]=_hb_font_draw_glyph=wasmExports["hb_font_draw_glyph"];Module["_hb_font_glyph_to_string"]=_hb_font_glyph_to_string=wasmExports["hb_font_glyph_to_string"];Module["_hb_font_create"]=_hb_font_create=wasmExports["hb_font_create"];Module["_hb_font_set_variations"]=_hb_font_set_variations=wasmExports["hb_font_set_variations"];Module["_hb_font_create_sub_font"]=_hb_font_create_sub_font=wasmExports["hb_font_create_sub_font"];Module["_hb_font_reference"]=_hb_font_reference=wasmExports["hb_font_reference"];Module["_hb_font_destroy"]=_hb_font_destroy=wasmExports["hb_font_destroy"];Module["_hb_font_set_funcs"]=_hb_font_set_funcs=wasmExports["hb_font_set_funcs"];Module["_hb_font_set_scale"]=_hb_font_set_scale=wasmExports["hb_font_set_scale"];Module["_hb_ot_layout_table_get_script_tags"]=_hb_ot_layout_table_get_script_tags=wasmExports["hb_ot_layout_table_get_script_tags"];Module["_hb_ot_layout_table_get_feature_tags"]=_hb_ot_layout_table_get_feature_tags=wasmExports["hb_ot_layout_table_get_feature_tags"];Module["_hb_ot_layout_script_get_language_tags"]=_hb_ot_layout_script_get_language_tags=wasmExports["hb_ot_layout_script_get_language_tags"];Module["_hb_ot_layout_language_get_feature_tags"]=_hb_ot_layout_language_get_feature_tags=wasmExports["hb_ot_layout_language_get_feature_tags"];Module["_hb_ot_layout_feature_get_name_ids"]=_hb_ot_layout_feature_get_name_ids=wasmExports["hb_ot_layout_feature_get_name_ids"];Module["_hb_ot_name_list_names"]=_hb_ot_name_list_names=wasmExports["hb_ot_name_list_names"];Module["_hb_ot_name_get_utf16"]=_hb_ot_name_get_utf16=wasmExports["hb_ot_name_get_utf16"];Module["_hb_set_create"]=_hb_set_create=wasmExports["hb_set_create"];Module["_hb_set_destroy"]=_hb_set_destroy=wasmExports["hb_set_destroy"];Module["_hb_ot_tag_to_script"]=_hb_ot_tag_to_script=wasmExports["hb_ot_tag_to_script"];Module["_hb_ot_tag_to_language"]=_hb_ot_tag_to_language=wasmExports["hb_ot_tag_to_language"];Module["_hb_ot_var_get_axis_infos"]=_hb_ot_var_get_axis_infos=wasmExports["hb_ot_var_get_axis_infos"];Module["_hb_set_get_population"]=_hb_set_get_population=wasmExports["hb_set_get_population"];Module["_hb_set_next_many"]=_hb_set_next_many=wasmExports["hb_set_next_many"];Module["_hb_shape"]=_hb_shape=wasmExports["hb_shape"];__emscripten_timeout=wasmExports["_emscripten_timeout"];__emscripten_stack_restore=wasmExports["_emscripten_stack_restore"];__emscripten_stack_alloc=wasmExports["_emscripten_stack_alloc"];_emscripten_stack_get_current=wasmExports["emscripten_stack_get_current"]}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();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()}}function preInit(){if(Module["preInit"]){if(typeof Module["preInit"]=="function")Module["preInit"]=[Module["preInit"]];while(Module["preInit"].length>0){Module["preInit"].shift()()}}}preInit();run();if(runtimeInitialized){moduleRtn=Module}else{moduleRtn=new Promise((resolve,reject)=>{readyPromiseResolve=resolve;readyPromiseReject=reject})}
2
2
  ;return moduleRtn}})();if(typeof exports==="object"&&typeof module==="object"){module.exports=createHarfBuzz;module.exports.default=createHarfBuzz}else if(typeof define==="function"&&define["amd"])define([],()=>createHarfBuzz);
package/hb.symbols CHANGED
@@ -4,6 +4,7 @@ _hb_blob_get_data
4
4
  _hb_blob_get_length
5
5
  _hb_buffer_add_utf16
6
6
  _hb_buffer_add_utf8
7
+ _hb_buffer_add_codepoints
7
8
  _hb_buffer_create
8
9
  _hb_buffer_destroy
9
10
  _hb_buffer_get_glyph_infos
@@ -73,6 +74,8 @@ _hb_ot_layout_language_get_feature_tags
73
74
  _hb_ot_layout_feature_get_name_ids
74
75
  _hb_ot_name_list_names
75
76
  _hb_ot_name_get_utf16
77
+ _hb_ot_tag_to_language
78
+ _hb_ot_tag_to_script
76
79
  _hb_ot_var_get_axis_infos
77
80
  _hb_script_from_string
78
81
  _hb_feature_from_string
package/hb.wasm CHANGED
Binary file
package/hbjs.js CHANGED
@@ -9,16 +9,20 @@ function hbjs(Module) {
9
9
 
10
10
  var freeFuncPtr = addFunction(function (ptr) { exports.free(ptr); }, 'vi');
11
11
 
12
- var HB_MEMORY_MODE_WRITABLE = 2;
13
- var HB_SET_VALUE_INVALID = -1;
14
- var HB_BUFFER_CONTENT_TYPE_GLYPHS = 2;
15
- var DONT_STOP = 0;
16
- var GSUB_PHASE = 1;
17
- var GPOS_PHASE = 2;
12
+ const TRACE_PHASE_DONT_STOP = 0;
13
+ const TRACE_PHASE_GSUB = 1;
14
+ const TRACE_PHASE_GPOS = 2;
18
15
 
19
16
  const STATIC_ARRAY_SIZE = 128
20
17
 
21
- function hb_tag(s) {
18
+ const HB_MEMORY_MODE_WRITABLE = 2;
19
+ const HB_SET_VALUE_INVALID = -1;
20
+ const HB_BUFFER_CONTENT_TYPE_GLYPHS = 2;
21
+ const HB_BUFFER_SERIALIZE_FORMAT_JSON = _hb_tag('JSON');
22
+ const HB_BUFFER_SERIALIZE_FLAG_NO_GLYPH_NAMES = 4;
23
+ const HB_OT_NAME_ID_INVALID = 0xFFFF;
24
+
25
+ function _hb_tag(s) {
22
26
  return (
23
27
  (s.charCodeAt(0) & 0xFF) << 24 |
24
28
  (s.charCodeAt(1) & 0xFF) << 16 |
@@ -27,11 +31,6 @@ function hbjs(Module) {
27
31
  );
28
32
  }
29
33
 
30
- var HB_BUFFER_SERIALIZE_FORMAT_JSON = hb_tag('JSON');
31
- var HB_BUFFER_SERIALIZE_FLAG_NO_GLYPH_NAMES = 4;
32
-
33
- const HB_OT_NAME_ID_INVALID = 0xFFFF;
34
-
35
34
  function _hb_untag(tag) {
36
35
  return [
37
36
  String.fromCharCode((tag >> 24) & 0xFF),
@@ -41,6 +40,58 @@ function hbjs(Module) {
41
40
  ].join('');
42
41
  }
43
42
 
43
+ function _utf8_ptr_to_string(ptr, length) {
44
+ let end;
45
+ if (length === undefined) end = Module.HEAPU8.indexOf(0, ptr);
46
+ else end = ptr + length;
47
+ return utf8Decoder.decode(Module.HEAPU8.subarray(ptr, end));
48
+ }
49
+
50
+ function _utf16_ptr_to_string(ptr, length) {
51
+ let end = ptr / 2 + length;
52
+ return String.fromCharCode.apply(null, Module.HEAPU16.subarray(ptr / 2, end));
53
+ }
54
+
55
+ /**
56
+ * Use when you know the input range should be ASCII.
57
+ * Faster than encoding to UTF-8
58
+ **/
59
+ function _string_to_ascii_ptr(text) {
60
+ const ptr = exports.malloc(text.length + 1);
61
+ for (let i = 0; i < text.length; ++i) {
62
+ const char = text.charCodeAt(i);
63
+ if (char > 127) throw new Error('Expected ASCII text');
64
+ Module.HEAPU8[ptr + i] = char;
65
+ }
66
+ Module.HEAPU8[ptr + text.length] = 0;
67
+ return {
68
+ ptr: ptr,
69
+ length: text.length,
70
+ free: function () { exports.free(ptr); }
71
+ };
72
+ }
73
+
74
+ function _string_to_utf8_ptr(text) {
75
+ const ptr = exports.malloc(text.length);
76
+ utf8Encoder.encodeInto(text, Module.HEAPU8.subarray(ptr, ptr + text.length));
77
+ return {
78
+ ptr: ptr,
79
+ length: text.length,
80
+ free: function () { exports.free(ptr); }
81
+ };
82
+ }
83
+
84
+ function _string_to_utf16_ptr(text) {
85
+ const ptr = exports.malloc(text.length * 2);
86
+ const words = new Uint16Array(Module.wasmMemory.buffer, ptr, text.length);
87
+ for (let i = 0; i < words.length; ++i) words[i] = text.charCodeAt(i);
88
+ return {
89
+ ptr: ptr,
90
+ length: words.length,
91
+ free: function () { exports.free(ptr); }
92
+ };
93
+ }
94
+
44
95
  function _buffer_flag(s) {
45
96
  if (s == "BOT") { return 0x1; }
46
97
  if (s == "EOT") { return 0x2; }
@@ -53,12 +104,11 @@ function hbjs(Module) {
53
104
 
54
105
  function _language_to_string(language) {
55
106
  var ptr = exports.hb_language_to_string(language);
56
- var str = utf8Decoder.decode(Module.HEAPU8.subarray(ptr, Module.HEAPU8.indexOf(0, ptr)));
57
- return str;
107
+ return _utf8_ptr_to_string(ptr);
58
108
  }
59
109
 
60
110
  function _language_from_string(str) {
61
- var languageStr = createAsciiString(str);
111
+ var languageStr = _string_to_ascii_ptr(str);
62
112
  var languagePtr = exports.hb_language_from_string(languageStr.ptr, -1);
63
113
  languageStr.free();
64
114
  return languagePtr;
@@ -86,7 +136,7 @@ function hbjs(Module) {
86
136
  * @param {number} setPtr Pointer of set
87
137
  * @returns {Uint32Array} Typed array instance
88
138
  */
89
- function typedArrayFromSet(setPtr) {
139
+ function _typed_array_from_set(setPtr) {
90
140
  const setCount = exports.hb_set_get_population(setPtr);
91
141
  const arrayPtr = exports.malloc(setCount << 2);
92
142
  const arrayOffset = arrayPtr >> 2;
@@ -113,7 +163,7 @@ function hbjs(Module) {
113
163
  * @param {string} table Table name
114
164
  */
115
165
  reference_table: function (table) {
116
- var blob = exports.hb_face_reference_table(ptr, hb_tag(table));
166
+ var blob = exports.hb_face_reference_table(ptr, _hb_tag(table));
117
167
  var length = exports.hb_blob_get_length(blob);
118
168
  if (!length) { return; }
119
169
  var blobptr = exports.hb_blob_get_data(blob, null);
@@ -146,7 +196,7 @@ function hbjs(Module) {
146
196
  collectUnicodes: function () {
147
197
  var unicodeSetPtr = exports.hb_set_create();
148
198
  exports.hb_face_collect_unicodes(ptr, unicodeSetPtr);
149
- var result = typedArrayFromSet(unicodeSetPtr);
199
+ var result = _typed_array_from_set(unicodeSetPtr);
150
200
  exports.hb_set_destroy(unicodeSetPtr);
151
201
  return result;
152
202
  },
@@ -156,7 +206,8 @@ function hbjs(Module) {
156
206
  * @param {string} table: The table to query, either "GSUB" or "GPOS".
157
207
  **/
158
208
  getTableScriptTags: function (table) {
159
- var tableTag = hb_tag(table);
209
+ var sp = Module.stackSave();
210
+ var tableTag = _hb_tag(table);
160
211
  var startOffset = 0;
161
212
  var scriptCount = STATIC_ARRAY_SIZE;
162
213
  var scriptCountPtr = Module.stackAlloc(4);
@@ -172,6 +223,7 @@ function hbjs(Module) {
172
223
  tags.push(...Array.from(scriptTags).map(_hb_untag));
173
224
  startOffset += scriptCount;
174
225
  }
226
+ Module.stackRestore(sp);
175
227
  return tags;
176
228
  },
177
229
  /**
@@ -180,7 +232,8 @@ function hbjs(Module) {
180
232
  * @param {string} table: The table to query, either "GSUB" or "GPOS".
181
233
  **/
182
234
  getTableFeatureTags: function (table) {
183
- var tableTag = hb_tag(table);
235
+ var sp = Module.stackSave();
236
+ var tableTag = _hb_tag(table);
184
237
  var startOffset = 0;
185
238
  var featureCount = STATIC_ARRAY_SIZE;
186
239
  var featureCountPtr = Module.stackAlloc(4);
@@ -196,7 +249,9 @@ function hbjs(Module) {
196
249
  tags.push(...Array.from(scriptTags).map(_hb_untag));
197
250
  startOffset += featureCount;
198
251
  }
252
+ Module.stackRestore(sp);
199
253
  return tags;
254
+
200
255
  },
201
256
  /**
202
257
  * Return language tags in the given face's GSUB or GPOS table, underneath
@@ -205,7 +260,8 @@ function hbjs(Module) {
205
260
  * @param {number} scriptIndex: The index of the script to query.
206
261
  **/
207
262
  getScriptLanguageTags: function (table, scriptIndex) {
208
- var tableTag = hb_tag(table);
263
+ var sp = Module.stackSave();
264
+ var tableTag = _hb_tag(table);
209
265
  var startOffset = 0;
210
266
  var languageCount = STATIC_ARRAY_SIZE;
211
267
  var languageCountPtr = Module.stackAlloc(4);
@@ -221,6 +277,7 @@ function hbjs(Module) {
221
277
  tags.push(...Array.from(languageTags).map(_hb_untag));
222
278
  startOffset += languageCount;
223
279
  }
280
+ Module.stackRestore(sp);
224
281
  return tags;
225
282
  },
226
283
  /**
@@ -231,7 +288,8 @@ function hbjs(Module) {
231
288
  * @param {number} languageIndex: The index of the language to query.
232
289
  **/
233
290
  getLanguageFeatureTags: function (table, scriptIndex, languageIndex) {
234
- var tableTag = hb_tag(table);
291
+ var sp = Module.stackSave();
292
+ var tableTag = _hb_tag(table);
235
293
  var startOffset = 0;
236
294
  var featureCount = STATIC_ARRAY_SIZE;
237
295
  var featureCountPtr = Module.stackAlloc(4);
@@ -247,12 +305,14 @@ function hbjs(Module) {
247
305
  tags.push(...Array.from(featureTags).map(_hb_untag));
248
306
  startOffset += featureCount;
249
307
  }
308
+ Module.stackRestore(sp);
250
309
  return tags;
251
310
  },
252
311
  /**
253
312
  * Return all names in the specified face's name table.
254
313
  **/
255
314
  listNames: function () {
315
+ var sp = Module.stackSave();
256
316
  var numEntriesPtr = Module.stackAlloc(4);
257
317
  var entriesPtr = exports.hb_ot_name_list_names(ptr, numEntriesPtr);
258
318
  var numEntries = Module.HEAPU32[numEntriesPtr / 4];
@@ -266,6 +326,7 @@ function hbjs(Module) {
266
326
  language: _language_to_string(Module.HEAPU32[(entriesPtr / 4) + (i * 3) + 2])
267
327
  });
268
328
  }
329
+ Module.stackRestore(sp);
269
330
  return entries;
270
331
  },
271
332
  /**
@@ -274,14 +335,16 @@ function hbjs(Module) {
274
335
  * @param {string} language The language of the name to get.
275
336
  **/
276
337
  getName: function (nameId, language) {
338
+ var sp = Module.stackSave();
277
339
  var languagePtr = _language_from_string(language);
278
340
  var nameLen = exports.hb_ot_name_get_utf16(ptr, nameId, languagePtr, 0, 0) + 1;
279
341
  var textSizePtr = Module.stackAlloc(4);
280
342
  var textPtr = exports.malloc(nameLen * 2);
281
343
  Module.HEAPU32[textSizePtr / 4] = nameLen;
282
344
  exports.hb_ot_name_get_utf16(ptr, nameId, languagePtr, textSizePtr, textPtr);
283
- var name = String.fromCharCode.apply(null, Module.HEAPU16.subarray(textPtr / 2, textPtr / 2 + nameLen - 1));
345
+ var name = _utf16_ptr_to_string(textPtr, nameLen - 1);
284
346
  exports.free(textPtr);
347
+ Module.stackRestore(sp);
285
348
  return name;
286
349
  },
287
350
  /**
@@ -290,7 +353,8 @@ function hbjs(Module) {
290
353
  * @param {number} featureIndex The index of the feature to query.
291
354
  **/
292
355
  getFeatureNameIds: function (table, featureIndex) {
293
- var tableTag = hb_tag(table);
356
+ var sp = Module.stackSave();
357
+ var tableTag = _hb_tag(table);
294
358
  var labelIdPtr = Module.stackAlloc(4);
295
359
  var tooltipIdPtr = Module.stackAlloc(4);
296
360
  var sampleIdPtr = Module.stackAlloc(4);
@@ -300,6 +364,7 @@ function hbjs(Module) {
300
364
  var found = exports.hb_ot_layout_feature_get_name_ids(ptr, tableTag, featureIndex,
301
365
  labelIdPtr, tooltipIdPtr, sampleIdPtr, numNamedParametersPtr, firstParameterIdPtr);
302
366
 
367
+ var names = null;
303
368
  if (found) {
304
369
  let uiLabelNameId = Module.HEAPU32[labelIdPtr / 4];
305
370
  let uiTooltipTextNameId = Module.HEAPU32[tooltipIdPtr / 4];
@@ -307,7 +372,7 @@ function hbjs(Module) {
307
372
  let numNamedParameters = Module.HEAPU32[numNamedParametersPtr / 4];
308
373
  let firstParameterId = Module.HEAPU32[firstParameterIdPtr / 4];
309
374
  let paramUiLabelNameIds = Array(numNamedParameters).fill().map((_, i) => firstParameterId + i);
310
- return {
375
+ names = {
311
376
  uiLabelNameId: uiLabelNameId == HB_OT_NAME_ID_INVALID ? null : uiLabelNameId,
312
377
  uiTooltipTextNameId: uiTooltipTextNameId == HB_OT_NAME_ID_INVALID ? null : uiTooltipTextNameId,
313
378
  sampleTextNameId: sampleTextNameId == HB_OT_NAME_ID_INVALID ? null : sampleTextNameId,
@@ -315,7 +380,8 @@ function hbjs(Module) {
315
380
  };
316
381
  }
317
382
 
318
- return null;
383
+ Module.stackRestore(sp);
384
+ return names;
319
385
  },
320
386
  /**
321
387
  * Free the object.
@@ -396,8 +462,7 @@ function hbjs(Module) {
396
462
  nameBuffer,
397
463
  nameBufferSize
398
464
  );
399
- var array = Module.HEAPU8.subarray(nameBuffer, nameBuffer + nameBufferSize);
400
- return utf8Decoder.decode(array.slice(0, array.indexOf(0)));
465
+ return _utf8_ptr_to_string(nameBuffer);
401
466
  }
402
467
 
403
468
  return {
@@ -414,26 +479,32 @@ function hbjs(Module) {
414
479
  * @returns {object} Object with ascender, descender, and lineGap properties.
415
480
  **/
416
481
  hExtents: function () {
482
+ var sp = Module.stackSave();
417
483
  var extentsPtr = Module.stackAlloc(12);
418
484
  exports.hb_font_get_h_extents(ptr, extentsPtr);
419
- return {
485
+ var extents = {
420
486
  ascender: Module.HEAP32[extentsPtr / 4],
421
487
  descender: Module.HEAP32[extentsPtr / 4 + 1],
422
488
  lineGap: Module.HEAP32[extentsPtr / 4 + 2],
423
489
  };
490
+ Module.stackRestore(sp);
491
+ return extents;
424
492
  },
425
493
  /**
426
494
  * Return font vertical extents.
427
495
  * @returns {object} Object with ascender, descender, and lineGap properties.
428
496
  **/
429
497
  vExtents: function () {
498
+ var sp = Module.stackSave();
430
499
  var extentsPtr = Module.stackAlloc(12);
431
500
  exports.hb_font_get_v_extents(ptr, extentsPtr);
432
- return {
501
+ var extents = {
433
502
  ascender: Module.HEAP32[extentsPtr / 4],
434
503
  descender: Module.HEAP32[extentsPtr / 4 + 1],
435
504
  lineGap: Module.HEAP32[extentsPtr / 4 + 2],
436
505
  };
506
+ Module.stackRestore(sp);
507
+ return extents;
437
508
  },
438
509
  glyphName: glyphName,
439
510
  glyphToPath: glyphToPath,
@@ -456,54 +527,64 @@ function hbjs(Module) {
456
527
  * @param {number} glyphId ID of the requested glyph in the font.
457
528
  **/
458
529
  glyphHOrigin: function (glyphId) {
530
+ var sp = Module.stackSave();
459
531
  let xPtr = Module.stackAlloc(4);
460
532
  let yPtr = Module.stackAlloc(4);
533
+ let origin = null;
461
534
  if (exports.hb_font_get_glyph_h_origin(ptr, glyphId, xPtr, yPtr)) {
462
- return [Module.HEAP32[xPtr / 4], Module.HEAP32[yPtr / 4]];
535
+ origin = [Module.HEAP32[xPtr / 4], Module.HEAP32[yPtr / 4]];
463
536
  }
464
- return null;
537
+ Module.stackRestore(sp);
538
+ return origin;
465
539
  },
466
540
  /**
467
541
  * Return glyph vertical origin.
468
542
  * @param {number} glyphId ID of the requested glyph in the font.
469
543
  **/
470
544
  glyphVOrigin: function (glyphId) {
545
+ var sp = Module.stackSave();
471
546
  let xPtr = Module.stackAlloc(4);
472
547
  let yPtr = Module.stackAlloc(4);
548
+ let origin = null;
473
549
  if (exports.hb_font_get_glyph_v_origin(ptr, glyphId, xPtr, yPtr)) {
474
- return [Module.HEAP32[xPtr / 4], Module.HEAP32[yPtr / 4]];
550
+ origin = [Module.HEAP32[xPtr / 4], Module.HEAP32[yPtr / 4]];
475
551
  }
476
- return null;
552
+ Module.stackRestore(sp);
553
+ return origin;
477
554
  },
478
555
  /**
479
556
  * Return glyph extents.
480
557
  * @param {number} glyphId ID of the requested glyph in the font.
481
558
  **/
482
559
  glyphExtents: function (glyphId) {
560
+ var sp = Module.stackSave();
483
561
  var extentsPtr = Module.stackAlloc(16);
562
+ var extents = null;
484
563
  if (exports.hb_font_get_glyph_extents(ptr, glyphId, extentsPtr)) {
485
- return {
564
+ extents = {
486
565
  xBearing: Module.HEAP32[extentsPtr / 4],
487
566
  yBearing: Module.HEAP32[extentsPtr / 4 + 1],
488
567
  width: Module.HEAP32[extentsPtr / 4 + 2],
489
568
  height: Module.HEAP32[extentsPtr / 4 + 3]
490
569
  };
491
570
  }
492
- return null;
571
+ Module.stackRestore(sp);
572
+ return extents;
493
573
  },
494
574
  /**
495
575
  * Return glyph ID from name.
496
576
  * @param {string} name Name of the requested glyph in the font.
497
577
  **/
498
578
  glyphFromName: function (name) {
499
- var glyphId = null;
579
+ var sp = Module.stackSave();
500
580
  var glyphIdPtr = Module.stackAlloc(4);
501
- var namePtr = exports.malloc(name.length + 1);
502
- utf8Encoder.encodeInto(name, Module.HEAPU8.subarray(namePtr, namePtr + name.length));
503
- if (exports.hb_font_get_glyph_from_name(ptr, namePtr, name.length, glyphIdPtr)) {
581
+ var namePtr = _string_to_utf8_ptr(name);
582
+ var glyphId = null;
583
+ if (exports.hb_font_get_glyph_from_name(ptr, namePtr.ptr, namePtr.length, glyphIdPtr)) {
504
584
  glyphId = Module.HEAPU32[glyphIdPtr / 4];
505
585
  }
506
- exports.free(namePtr);
586
+ namePtr.free();
587
+ Module.stackRestore(sp);
507
588
  return glyphId;
508
589
  },
509
590
  /**
@@ -535,7 +616,7 @@ function hbjs(Module) {
535
616
  var entries = Object.entries(variations);
536
617
  var vars = exports.malloc(8 * entries.length);
537
618
  entries.forEach(function (entry, i) {
538
- Module.HEAPU32[vars / 4 + i * 2 + 0] = hb_tag(entry[0]);
619
+ Module.HEAPU32[vars / 4 + i * 2 + 0] = _hb_tag(entry[0]);
539
620
  Module.HEAPF32[vars / 4 + i * 2 + 1] = entry[1];
540
621
  });
541
622
  exports.hb_font_set_variations(ptr, vars, entries.length);
@@ -617,7 +698,7 @@ function hbjs(Module) {
617
698
  setGlyphFromNameFunc: function (func) {
618
699
  let funcPtr = addFunction(function (fontPtr, font_data, namePtr, len, glyphPtr, user_data) {
619
700
  let font = createFont(null, fontPtr);
620
- let name = utf8Decoder.decode(Module.HEAPU8.subarray(namePtr, namePtr + len));
701
+ let name = _utf8_ptr_to_string(namePtr, len);
621
702
  let glyph = func(font, name);
622
703
  font.destroy();
623
704
  if (glyph) {
@@ -864,36 +945,6 @@ function hbjs(Module) {
864
945
  };
865
946
  }
866
947
 
867
- /**
868
- * Use when you know the input range should be ASCII.
869
- * Faster than encoding to UTF-8
870
- **/
871
- function createAsciiString(text) {
872
- var ptr = exports.malloc(text.length + 1);
873
- for (let i = 0; i < text.length; ++i) {
874
- const char = text.charCodeAt(i);
875
- if (char > 127) throw new Error('Expected ASCII text');
876
- Module.HEAPU8[ptr + i] = char;
877
- }
878
- Module.HEAPU8[ptr + text.length] = 0;
879
- return {
880
- ptr: ptr,
881
- length: text.length,
882
- free: function () { exports.free(ptr); }
883
- };
884
- }
885
-
886
- function createJsString(text) {
887
- const ptr = exports.malloc(text.length * 2);
888
- const words = new Uint16Array(Module.wasmMemory.buffer, ptr, text.length);
889
- for (let i = 0; i < words.length; ++i) words[i] = text.charCodeAt(i);
890
- return {
891
- ptr: ptr,
892
- length: words.length,
893
- free: function () { exports.free(ptr); }
894
- };
895
- }
896
-
897
948
  /**
898
949
  * Create an object representing a Harfbuzz buffer.
899
950
  **/
@@ -904,13 +955,30 @@ function hbjs(Module) {
904
955
  /**
905
956
  * Add text to the buffer.
906
957
  * @param {string} text Text to be added to the buffer.
958
+ * @param {number} itemOffset Optional. The offset of the first character to add to the buffer.
959
+ * @param {number} itemLength Optional. The number of characters to add to the buffer, or null for the end of text.
907
960
  **/
908
- addText: function (text) {
909
- const str = createJsString(text);
910
- exports.hb_buffer_add_utf16(ptr, str.ptr, str.length, 0, str.length);
961
+ addText: function (text, itemOffset = 0, itemLength = null) {
962
+ const str = _string_to_utf16_ptr(text);
963
+ if (itemLength == null) itemLength = str.length;
964
+ exports.hb_buffer_add_utf16(ptr, str.ptr, str.length, itemOffset, itemLength);
911
965
  str.free();
912
966
  },
913
967
  /**
968
+ * Add code points to the buffer.
969
+ * @param {number[]} codePoints Array of code points to be added to the buffer.
970
+ * @param {number} itemOffset Optional. The offset of the first code point to add to the buffer.
971
+ * @param {number} itemLength Optional. The number of code points to add to the buffer, or null for the end of the array.
972
+ */
973
+ addCodePoints: function (codePoints, itemOffset = 0, itemLength = null) {
974
+ let codePointsPtr = exports.malloc(codePoints.length * 4);
975
+ let codePointsArray = new Uint32Array(Module.wasmMemory.buffer, codePointsPtr, codePoints.length);
976
+ codePointsArray.set(codePoints);
977
+ if (itemLength == null) itemLength = codePoints.length;
978
+ exports.hb_buffer_add_codepoints(ptr, codePointsPtr, codePoints.length, itemOffset, itemLength);
979
+ exports.free(codePointsPtr);
980
+ },
981
+ /**
914
982
  * Set buffer script, language and direction.
915
983
  *
916
984
  * This needs to be done before shaping.
@@ -953,7 +1021,7 @@ function hbjs(Module) {
953
1021
  * @param {string} language: The buffer language
954
1022
  */
955
1023
  setLanguage: function (language) {
956
- var str = createAsciiString(language);
1024
+ var str = _string_to_ascii_ptr(language);
957
1025
  exports.hb_buffer_set_language(ptr, exports.hb_language_from_string(str.ptr, -1));
958
1026
  str.free();
959
1027
  },
@@ -962,7 +1030,7 @@ function hbjs(Module) {
962
1030
  * @param {string} script: The buffer script
963
1031
  */
964
1032
  setScript: function (script) {
965
- var str = createAsciiString(script);
1033
+ var str = _string_to_ascii_ptr(script);
966
1034
  exports.hb_buffer_set_script(ptr, exports.hb_script_from_string(str.ptr, -1));
967
1035
  str.free();
968
1036
  },
@@ -1036,7 +1104,7 @@ function hbjs(Module) {
1036
1104
  features = features.split(",");
1037
1105
  featuresPtr = exports.malloc(16 * features.length);
1038
1106
  features.forEach(function (feature, i) {
1039
- var str = createAsciiString(feature);
1107
+ var str = _string_to_ascii_ptr(feature);
1040
1108
  if (exports.hb_feature_from_string(str.ptr, -1, featuresPtr + featuresLen * 16))
1041
1109
  featuresLen++;
1042
1110
  str.free();
@@ -1067,7 +1135,7 @@ function hbjs(Module) {
1067
1135
  */
1068
1136
  function shapeWithTrace(font, buffer, features, stop_at, stop_phase) {
1069
1137
  var trace = [];
1070
- var currentPhase = DONT_STOP;
1138
+ var currentPhase = TRACE_PHASE_DONT_STOP;
1071
1139
  var stopping = false;
1072
1140
  var failure = false;
1073
1141
 
@@ -1075,11 +1143,11 @@ function hbjs(Module) {
1075
1143
  var traceBufPtr = exports.malloc(traceBufLen);
1076
1144
 
1077
1145
  var traceFunc = function (bufferPtr, fontPtr, messagePtr, user_data) {
1078
- var message = utf8Decoder.decode(Module.HEAPU8.subarray(messagePtr, Module.HEAPU8.indexOf(0, messagePtr)));
1146
+ var message = _utf8_ptr_to_string(messagePtr);
1079
1147
  if (message.startsWith("start table GSUB"))
1080
- currentPhase = GSUB_PHASE;
1148
+ currentPhase = TRACE_PHASE_GSUB;
1081
1149
  else if (message.startsWith("start table GPOS"))
1082
- currentPhase = GPOS_PHASE;
1150
+ currentPhase = TRACE_PHASE_GPOS;
1083
1151
 
1084
1152
  if (currentPhase != stop_phase)
1085
1153
  stopping = false;
@@ -1087,7 +1155,7 @@ function hbjs(Module) {
1087
1155
  if (failure)
1088
1156
  return 1;
1089
1157
 
1090
- if (stop_phase != DONT_STOP && currentPhase == stop_phase && message.startsWith("end lookup " + stop_at))
1158
+ if (stop_phase != TRACE_PHASE_DONT_STOP && currentPhase == stop_phase && message.startsWith("end lookup " + stop_at))
1091
1159
  stopping = true;
1092
1160
 
1093
1161
  if (stopping)
@@ -1103,7 +1171,7 @@ function hbjs(Module) {
1103
1171
 
1104
1172
  trace.push({
1105
1173
  m: message,
1106
- t: JSON.parse(utf8Decoder.decode(Module.HEAPU8.subarray(traceBufPtr, Module.HEAPU8.indexOf(0, traceBufPtr)))),
1174
+ t: JSON.parse(_utf8_ptr_to_string(traceBufPtr)),
1107
1175
  glyphs: exports.hb_buffer_get_content_type(bufferPtr) == HB_BUFFER_CONTENT_TYPE_GLYPHS,
1108
1176
  });
1109
1177
 
@@ -1133,8 +1201,29 @@ function hbjs(Module) {
1133
1201
 
1134
1202
  function version_string() {
1135
1203
  var versionPtr = exports.hb_version_string();
1136
- var version = utf8Decoder.decode(Module.HEAPU8.subarray(versionPtr, Module.HEAPU8.indexOf(0, versionPtr)));
1137
- return version;
1204
+ return _utf8_ptr_to_string(versionPtr);
1205
+ }
1206
+
1207
+ /**
1208
+ * Convert an OpenType script tag to HarfBuzz script.
1209
+ * @param {string} tag: The tag to convert.
1210
+ * @returns {string}: The script.
1211
+ */
1212
+ function otTagToScript(tag) {
1213
+ var hbTag = _hb_tag(tag);
1214
+ var script = exports.hb_ot_tag_to_script(hbTag);
1215
+ return _hb_untag(script);
1216
+ }
1217
+
1218
+ /**
1219
+ * Convert an OpenType language tag to HarfBuzz language.
1220
+ * @param {string} tag: The tag to convert.
1221
+ * @returns {string}: The language.
1222
+ */
1223
+ function otTagToLanguage(tag) {
1224
+ var hbTag = _hb_tag(tag);
1225
+ var language = exports.hb_ot_tag_to_language(hbTag);
1226
+ return _language_to_string(language);
1138
1227
  }
1139
1228
 
1140
1229
  return {
@@ -1147,6 +1236,8 @@ function hbjs(Module) {
1147
1236
  shapeWithTrace: shapeWithTrace,
1148
1237
  version: version,
1149
1238
  version_string: version_string,
1239
+ otTagToScript: otTagToScript,
1240
+ otTagToLanguage: otTagToLanguage,
1150
1241
  };
1151
1242
  }
1152
1243
 
package/package.json CHANGED
@@ -1,37 +1,38 @@
1
1
  {
2
- "name": "harfbuzzjs",
3
- "version": "0.5.0",
4
- "description": "Minimal version of HarfBuzz for JavaScript use",
5
- "main": "index.js",
6
- "scripts": {
7
- "test": "mocha test/index.js"
8
- },
9
- "keywords": [
10
- "harfbuzz",
11
- "opentype",
12
- "truetype",
13
- "ttf",
14
- "otf",
15
- "graphics",
16
- "complex scripts",
17
- "typography",
18
- "font rendering",
19
- "font",
20
- "fonts",
21
- "emoji"
22
- ],
23
- "repository": {
24
- "type": "git",
25
- "url": "git+https://github.com/harfbuzz/harfbuzzjs.git"
26
- },
27
- "author": "Ebrahim Byagowi <ebrahim@gnu.org>",
28
- "license": "MIT",
29
- "bugs": {
30
- "url": "https://github.com/harfbuzz/harfbuzzjs/issues"
31
- },
32
- "homepage": "https://github.com/harfbuzz/harfbuzzjs#readme",
33
- "devDependencies": {
34
- "chai": "^4.3.7",
35
- "mocha": "^10.2.0"
36
- }
37
- }
2
+ "name": "harfbuzzjs",
3
+ "version": "0.7.0",
4
+ "description": "Minimal version of HarfBuzz for JavaScript use",
5
+ "main": "index.js",
6
+ "scripts": {
7
+ "prepare": "make",
8
+ "test": "make test"
9
+ },
10
+ "keywords": [
11
+ "harfbuzz",
12
+ "opentype",
13
+ "truetype",
14
+ "ttf",
15
+ "otf",
16
+ "graphics",
17
+ "complex scripts",
18
+ "typography",
19
+ "font rendering",
20
+ "font",
21
+ "fonts",
22
+ "emoji"
23
+ ],
24
+ "repository": {
25
+ "type": "git",
26
+ "url": "git+https://github.com/harfbuzz/harfbuzzjs.git"
27
+ },
28
+ "author": "Ebrahim Byagowi <ebrahim@gnu.org>",
29
+ "license": "MIT",
30
+ "bugs": {
31
+ "url": "https://github.com/harfbuzz/harfbuzzjs/issues"
32
+ },
33
+ "homepage": "https://github.com/harfbuzz/harfbuzzjs#readme",
34
+ "devDependencies": {
35
+ "chai": "^4.3.7",
36
+ "mocha": "^10.2.0"
37
+ }
38
+ }
package/test/index.js CHANGED
@@ -586,6 +586,20 @@ describe('shape', function () {
586
586
  expect(glyphs[2]).to.deep.equal({ cl: 2, g: 70, ax: 480, ay: 0, dx: 0, dy: 0, flags: 0 } /* c */);
587
587
  });
588
588
 
589
+ it('shape Latin string code points', function () {
590
+ blob = hb.createBlob(fs.readFileSync(path.join(__dirname, 'fonts/noto/NotoSans-Regular.ttf')));
591
+ face = hb.createFace(blob);
592
+ font = hb.createFont(face);
593
+ buffer = hb.createBuffer();
594
+ buffer.addCodePoints([...'abc'].map(c => c.codePointAt(0)));
595
+ buffer.guessSegmentProperties();
596
+ hb.shape(font, buffer)
597
+ const glyphs = buffer.json();
598
+ expect(glyphs[0]).to.deep.equal({ cl: 0, g: 68, ax: 561, ay: 0, dx: 0, dy: 0, flags: 0 } /* a */);
599
+ expect(glyphs[1]).to.deep.equal({ cl: 1, g: 69, ax: 615, ay: 0, dx: 0, dy: 0, flags: 0 } /* b */);
600
+ expect(glyphs[2]).to.deep.equal({ cl: 2, g: 70, ax: 480, ay: 0, dx: 0, dy: 0, flags: 0 } /* c */);
601
+ });
602
+
589
603
  it('shape Arabic string', function () {
590
604
  blob = hb.createBlob(fs.readFileSync(path.join(__dirname, 'fonts/noto/NotoSansArabic-Variable.ttf')));
591
605
  face = hb.createFace(blob);
@@ -601,6 +615,32 @@ describe('shape', function () {
601
615
  expect(glyphs[3]).to.deep.equal({ cl: 0, g: 50, ax: 235, ay: 0, dx: 0, dy: 0, flags: 0 } /* أ */);
602
616
  });
603
617
 
618
+ it('shape Arabic string item', function () {
619
+ blob = hb.createBlob(fs.readFileSync(path.join(__dirname, 'fonts/noto/NotoSansArabic-Variable.ttf')));
620
+ face = hb.createFace(blob);
621
+ font = hb.createFont(face);
622
+ buffer = hb.createBuffer();
623
+ buffer.addText('أبجد', 1, 2);
624
+ buffer.guessSegmentProperties();
625
+ hb.shape(font, buffer)
626
+ const glyphs = buffer.json();
627
+ expect(glyphs[0]).to.deep.equal({ cl: 2, g: 529, ax: 637, ay: 0, dx: 0, dy: 0, flags: 1 } /* ج */);
628
+ expect(glyphs[1]).to.deep.equal({ cl: 1, g: 101, ax: 269, ay: 0, dx: 0, dy: 0, flags: 0 } /* ب */);
629
+ });
630
+
631
+ it('shape Arabic code points item', function () {
632
+ blob = hb.createBlob(fs.readFileSync(path.join(__dirname, 'fonts/noto/NotoSansArabic-Variable.ttf')));
633
+ face = hb.createFace(blob);
634
+ font = hb.createFont(face);
635
+ buffer = hb.createBuffer();
636
+ buffer.addCodePoints([...'أبجد'].map(c => c.codePointAt(0)), 1, 2);
637
+ buffer.guessSegmentProperties();
638
+ hb.shape(font, buffer)
639
+ const glyphs = buffer.json();
640
+ expect(glyphs[0]).to.deep.equal({ cl: 2, g: 529, ax: 637, ay: 0, dx: 0, dy: 0, flags: 1 } /* ج */);
641
+ expect(glyphs[1]).to.deep.equal({ cl: 1, g: 101, ax: 269, ay: 0, dx: 0, dy: 0, flags: 0 } /* ب */);
642
+ });
643
+
604
644
  it('shape with tracing', function () {
605
645
  blob = hb.createBlob(fs.readFileSync(path.join(__dirname, 'fonts/noto/NotoSans-Regular.ttf')));
606
646
  face = hb.createFace(blob);
@@ -718,8 +758,51 @@ describe('misc', function () {
718
758
  expect(version).to.have.property('micro').that.is.a('number');
719
759
  expect(version.major).to.be.at.least(10);
720
760
  });
761
+
721
762
  it('get version string', function () {
722
763
  const version_string = hb.version_string();
723
764
  expect(version_string).to.match(/^\d+\.\d+\.\d+$/);
724
765
  });
766
+
767
+ it('convert OpenType tag to script', function () {
768
+ expect(hb.otTagToScript('arab')).to.equal('Arab');
769
+ expect(hb.otTagToScript('latn')).to.equal('Latn');
770
+ expect(hb.otTagToScript('dev2')).to.equal('Deva');
771
+ expect(hb.otTagToScript('nko ')).to.equal('Nkoo');
772
+ expect(hb.otTagToScript('DFLT')).to.equal('\0\0\0\0');
773
+ });
774
+
775
+ it('convert OpenType tag to language', function () {
776
+ expect(hb.otTagToLanguage('ARA ')).to.equal('ar');
777
+ expect(hb.otTagToLanguage('ENG ')).to.equal('en');
778
+ expect(hb.otTagToLanguage('BAD0')).to.equal('bad');
779
+ expect(hb.otTagToLanguage('SYRE')).to.equal('und-syre');
780
+ });
781
+
782
+ it("test that calling functions repeatedly doesn't exhaust memory", function () {
783
+ blob = hb.createBlob(fs.readFileSync(path.join(__dirname, 'fonts/noto/NotoSans-Regular.ttf')));
784
+ face = hb.createFace(blob);
785
+ font = hb.createFont(face);
786
+ for (let i = 0; i < 10000; i++) {
787
+ expect(face.listNames()).to.not.be.null;
788
+ expect(face.getName(0, "en")).to.not.be.null;
789
+ expect(font.hExtents()).to.not.be.null;
790
+ expect(font.vExtents()).to.not.be.null;
791
+ expect(font.glyphHOrigin(0)).to.not.be.null;
792
+ expect(font.glyphVOrigin(0)).to.be.null;
793
+ expect(font.glyphExtents(0)).to.not.be.null;
794
+ expect(font.glyphFromName("a")).to.not.be.null;
795
+ for (let tableTag of ["GSUB", "GPOS"]) {
796
+ expect(face.getTableFeatureTags(tableTag)).to.not.be.null;
797
+ expect(face.getTableScriptTags(tableTag)).to.not.be.null;
798
+ expect(face.getScriptLanguageTags(tableTag, 0)).to.not.be.null;
799
+ expect(face.getLanguageFeatureTags(tableTag, 0, 0)).to.not.be.null;
800
+ if (tableTag === "GSUB") {
801
+ expect(face.getFeatureNameIds(tableTag, 50)).to.not.be.null;
802
+ } else {
803
+ expect(face.getFeatureNameIds(tableTag, 50)).to.be.null;
804
+ }
805
+ }
806
+ }
807
+ });
725
808
  });
package/build-subset.sh DELETED
@@ -1,20 +0,0 @@
1
- #!/bin/bash
2
- set -e
3
-
4
- em++ \
5
- -std=c++11 \
6
- -fno-exceptions \
7
- -fno-rtti \
8
- -fno-threadsafe-statics \
9
- -fvisibility-inlines-hidden \
10
- -Oz \
11
- -I. \
12
- -DHB_TINY \
13
- -DHB_USE_INTERNAL_QSORT \
14
- -DHB_CONFIG_OVERRIDE_H=\"config-override-subset.h\" \
15
- -DHB_EXPERIMENTAL_API \
16
- --no-entry \
17
- -s EXPORTED_FUNCTIONS=@hb-subset.symbols \
18
- -s INITIAL_MEMORY=65MB \
19
- -o hb-subset.wasm \
20
- harfbuzz/src/harfbuzz-subset.cc
package/build.sh DELETED
@@ -1,27 +0,0 @@
1
- #!/bin/bash
2
- set -e
3
-
4
- em++ \
5
- -std=c++11 \
6
- -fno-exceptions \
7
- -fno-rtti \
8
- -fno-threadsafe-statics \
9
- -fvisibility-inlines-hidden \
10
- -flto \
11
- -Oz \
12
- -I. \
13
- -DHB_TINY \
14
- -DHB_USE_INTERNAL_QSORT \
15
- -DHB_CONFIG_OVERRIDE_H=\"config-override.h\" \
16
- -DHB_EXPERIMENTAL_API \
17
- --no-entry \
18
- -s MODULARIZE \
19
- -s EXPORT_NAME=createHarfBuzz \
20
- -s EXPORTED_FUNCTIONS=@hb.symbols \
21
- -s EXPORTED_RUNTIME_METHODS='["addFunction", "removeFunction", "stackAlloc", "wasmMemory", "wasmExports", "HEAP8", "HEAPU8", "HEAPU16", "HEAP32", "HEAPU32", "HEAPF32"]' \
22
- -s INITIAL_MEMORY=256KB \
23
- -s ALLOW_MEMORY_GROWTH \
24
- -s ALLOW_TABLE_GROWTH \
25
- -lexports.js \
26
- -o hb.js \
27
- harfbuzz/src/harfbuzz.cc