diff --git a/src/hb-wasm-api-blob.hh b/src/hb-wasm-api-blob.hh index 26b022bc3..310f4023f 100644 --- a/src/hb-wasm-api-blob.hh +++ b/src/hb-wasm-api-blob.hh @@ -34,7 +34,7 @@ namespace wasm { HB_WASM_API (void, blob_free) (HB_WASM_EXEC_ENV ptr_d(blob_t, blob)) { - HB_OUT_PARAM (blob_t, blob); + HB_PTR_PARAM (blob_t, blob); if (unlikely (!blob)) return; diff --git a/src/hb-wasm-api-buffer.hh b/src/hb-wasm-api-buffer.hh index 1d9612e88..7cfdb62f6 100644 --- a/src/hb-wasm-api-buffer.hh +++ b/src/hb-wasm-api-buffer.hh @@ -39,7 +39,7 @@ HB_WASM_API (void, buffer_contents_realloc) (HB_WASM_EXEC_ENV ptr_d(buffer_contents_t, contents), uint32_t size) { - HB_OUT_PARAM (buffer_contents_t, contents); + HB_PTR_PARAM (buffer_contents_t, contents); if (unlikely (!contents)) return; @@ -69,7 +69,7 @@ HB_WASM_API (void, buffer_contents_realloc) (HB_WASM_EXEC_ENV HB_WASM_API (void, buffer_contents_free) (HB_WASM_EXEC_ENV ptr_d(buffer_contents_t, contents)) { - HB_OUT_PARAM (buffer_contents_t, contents); + HB_PTR_PARAM (buffer_contents_t, contents); if (unlikely (!contents)) return; @@ -101,7 +101,7 @@ HB_WASM_API (bool_t, buffer_set_contents) (HB_WASM_EXEC_ENV ptr_d(const buffer_contents_t, contents)) { HB_REF2OBJ (buffer); - HB_OUT_PARAM (buffer_contents_t, contents); + HB_PTR_PARAM (buffer_contents_t, contents); if (unlikely (!contents)) return false; diff --git a/src/hb-wasm-api-font.hh b/src/hb-wasm-api-font.hh index e5a6ff7fd..e3e5453d7 100644 --- a/src/hb-wasm-api-font.hh +++ b/src/hb-wasm-api-font.hh @@ -49,8 +49,8 @@ HB_WASM_API (void, font_get_scale) (HB_WASM_EXEC_ENV { HB_REF2OBJ (font); - HB_OUT_PARAM(int32_t, x_scale); - HB_OUT_PARAM(int32_t, y_scale); + HB_PTR_PARAM(int32_t, x_scale); + HB_PTR_PARAM(int32_t, y_scale); hb_font_get_scale (font, x_scale, y_scale); } @@ -91,7 +91,7 @@ HB_WASM_API (bool_t, font_get_glyph_extents) (HB_WASM_EXEC_ENV ptr_d(glyph_extents_t, extents)) { HB_REF2OBJ (font); - HB_OUT_PARAM (glyph_extents_t, extents); + HB_PTR_PARAM (glyph_extents_t, extents); if (unlikely (!extents)) return false; diff --git a/src/hb-wasm-api-list.hh b/src/hb-wasm-api-list.hh index 0ded35980..8d05f2914 100644 --- a/src/hb-wasm-api-list.hh +++ b/src/hb-wasm-api-list.hh @@ -80,7 +80,7 @@ static NativeSymbol _hb_wasm_native_symbols[] = NATIVE_SYMBOL ("(ii$*)", font_glyph_to_string), /* shape */ - NATIVE_SYMBOL ("(ii$)i", shape_with), + NATIVE_SYMBOL ("(iiii$)i", shape_with), /* debug */ #ifdef HB_DEBUG_WASM diff --git a/src/hb-wasm-api-shape.hh b/src/hb-wasm-api-shape.hh index d141b3c69..7e12969f7 100644 --- a/src/hb-wasm-api-shape.hh +++ b/src/hb-wasm-api-shape.hh @@ -31,19 +31,29 @@ namespace hb { namespace wasm { +static_assert (sizeof (feature_t) == sizeof (hb_feature_t), ""); + HB_WASM_INTERFACE (bool_t, shape_with) (HB_WASM_EXEC_ENV ptr_d(font_t, font), ptr_d(buffer_t, buffer), + ptr_d(const feature_t, features), + uint32_t num_features, const char *shaper) { + if (unlikely (0 == strcmp (shaper, "wasm"))) + return false; + HB_REF2OBJ (font); HB_REF2OBJ (buffer); - if (0 == strcmp (shaper, "wasm")) + HB_ARRAY_PARAM (const feature_t, features, num_features); + if (unlikely (!features && num_features)) return false; const char * shaper_list[] = {shaper, nullptr}; - return hb_shape_full (font, buffer, nullptr, 0, shaper_list); + return hb_shape_full (font, buffer, + (hb_feature_t *) features, num_features, + shaper_list); } diff --git a/src/hb-wasm-api.h b/src/hb-wasm-api.h index a59b405a4..acfe69a11 100644 --- a/src/hb-wasm-api.h +++ b/src/hb-wasm-api.h @@ -225,17 +225,29 @@ HB_WASM_API (void, font_glyph_to_string) (HB_WASM_EXEC_ENV /* shape */ +typedef struct { + tag_t tag; + uint32_t value; + uint32_t start; + uint32_t end; +} feature_t; +#define FEATURE_GLOBAL_START 0 +#define FEATURE_GLOBAL_END ((uint32_t) -1) + HB_WASM_INTERFACE (bool_t, shape_with) (HB_WASM_EXEC_ENV ptr_d(font_t, font), ptr_d(buffer_t, buffer), + ptr_d(const feature_t, features), + uint32_t num_features, const char *shaper); - -/* shape interface */ +/* Implement this in your shaper. */ HB_WASM_INTERFACE (bool_t, shape) (HB_WASM_EXEC_ENV ptr_d(font_t, font), - ptr_d(buffer_t, buffer)); + ptr_d(buffer_t, buffer), + ptr_d(const feature_t, features), + uint32_t num_features); HB_WASM_END_DECLS diff --git a/src/hb-wasm-api.hh b/src/hb-wasm-api.hh index f5ef9e487..f7e5565be 100644 --- a/src/hb-wasm-api.hh +++ b/src/hb-wasm-api.hh @@ -91,7 +91,7 @@ HB_INTERNAL extern hb_user_data_key_t _hb_wasm_ref_type_key; } \ type &name = *_name_ptr -#define HB_OUT_PARAM(type, name) \ +#define HB_PTR_PARAM(type, name) \ type *name = nullptr; \ HB_STMT_START { \ if (likely (wasm_runtime_validate_app_addr (module_inst, \ @@ -99,5 +99,14 @@ HB_INTERNAL extern hb_user_data_key_t _hb_wasm_ref_type_key; name = (type *) wasm_runtime_addr_app_to_native (module_inst, name##ptr); \ } HB_STMT_END +#define HB_ARRAY_PARAM(type, name, length) \ + type *name = nullptr; \ + HB_STMT_START { \ + if (likely (!hb_unsigned_mul_overflows (length, sizeof (type)) && \ + wasm_runtime_validate_app_addr (module_inst, \ + name##ptr, length * sizeof (type)))) \ + name = (type *) wasm_runtime_addr_app_to_native (module_inst, name##ptr); \ + } HB_STMT_END + #endif /* HB_WASM_API_HH */ diff --git a/src/hb-wasm-shape.cc b/src/hb-wasm-shape.cc index 4fe2ab511..317fb9cf0 100644 --- a/src/hb-wasm-shape.cc +++ b/src/hb-wasm-shape.cc @@ -197,17 +197,27 @@ _hb_wasm_shape (hb_shape_plan_t *shape_plan, } wasm_val_t results[1]; - wasm_val_t arguments[2]; + wasm_val_t arguments[4]; results[0].kind = WASM_I32; arguments[0].kind = WASM_I32; arguments[0].of.i32 = fontref; arguments[1].kind = WASM_I32; arguments[1].of.i32 = bufferref; + arguments[2].kind = WASM_I32; + arguments[2].of.i32 = wasm_runtime_module_dup_data (module_inst, + (const char *) features, + num_features * sizeof (features[0])); + arguments[3].kind = WASM_I32; + arguments[3].of.i32 = num_features; ret = wasm_runtime_call_wasm_a (exec_env, shape_func, ARRAY_LENGTH (results), results, ARRAY_LENGTH (arguments), arguments); + + + wasm_runtime_module_free (module_inst, arguments[2].of.i32); + if (unlikely (!ret)) { DEBUG_MSG (WASM, module_inst, "Calling shape function failed: %s", diff --git a/src/wasm-graphite/shape.cc b/src/wasm-graphite/shape.cc index e1a863b10..a1f140867 100644 --- a/src/wasm-graphite/shape.cc +++ b/src/wasm-graphite/shape.cc @@ -36,7 +36,10 @@ static void free_table (const void *data, const void *table_data) } bool_t -shape (font_t *font, buffer_t *buffer) +shape (font_t *font, + buffer_t *buffer, + const feature_t *features, + uint32_t num_features) { direction_t direction = buffer_get_direction (buffer); direction_t horiz_dir = script_get_horizontal_direction (buffer_get_script (buffer)); diff --git a/src/wasm-sample/shape-fallback.cc b/src/wasm-sample/shape-fallback.cc index 11853c402..ecb90d030 100644 --- a/src/wasm-sample/shape-fallback.cc +++ b/src/wasm-sample/shape-fallback.cc @@ -9,7 +9,10 @@ void debugprint2 (const char *s, int32_t, int32_t); } bool_t -shape (font_t *font, buffer_t *buffer) +shape (font_t *font, + buffer_t *buffer, + const feature_t *features, + uint32_t num_features) { face_t *face = font_get_face (font); diff --git a/src/wasm-sample/shape-ot.cc b/src/wasm-sample/shape-ot.cc index 10e1e723d..98276ec49 100644 --- a/src/wasm-sample/shape-ot.cc +++ b/src/wasm-sample/shape-ot.cc @@ -8,7 +8,10 @@ void debugprint2 (const char *s, int32_t, int32_t); } bool_t -shape (font_t *font, buffer_t *buffer) +shape (font_t *font, + buffer_t *buffer, + const feature_t *features, + uint32_t num_features) { - return shape_with (font, buffer, "ot"); + return shape_with (font, buffer, features, num_features, "ot"); }