From 65966e0c3da0fdb5a59abcc76533dfceccbc1425 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Sat, 25 Feb 2023 08:59:03 -0700 Subject: [PATCH] [wasm-api] Add font_copy_glyph_outline --- src/hb-wasm-api-font.hh | 46 +++++++++++++++++++++++++++++ src/hb-wasm-api-list.hh | 1 + src/hb-wasm-api.h | 36 ++++++++++++++++++++-- src/wasm/sample/c/shape-fallback.cc | 4 +++ 4 files changed, 85 insertions(+), 2 deletions(-) diff --git a/src/hb-wasm-api-font.hh b/src/hb-wasm-api-font.hh index e3e5453d7..d1401c7e0 100644 --- a/src/hb-wasm-api-font.hh +++ b/src/hb-wasm-api-font.hh @@ -27,6 +27,8 @@ #include "hb-wasm-api.hh" +#include "hb-outline.hh" + namespace hb { namespace wasm { @@ -109,6 +111,50 @@ HB_WASM_API (void, font_glyph_to_string) (HB_WASM_EXEC_ENV hb_font_glyph_to_string (font, glyph, s, size); } +static_assert (sizeof (glyph_outline_point_t) == sizeof (hb_outline_point_t), ""); +static_assert (sizeof (uint32_t) == sizeof (hb_outline_t::contours[0]), ""); + +HB_WASM_API (bool_t, font_copy_glyph_outline) (HB_WASM_EXEC_ENV + ptr_d(font_t, font), + codepoint_t glyph, + ptr_d(glyph_outline_t, outline)) +{ + HB_REF2OBJ (font); + HB_PTR_PARAM (glyph_outline_t, outline); + if (unlikely (!outline)) + return false; + + hb_outline_t hb_outline; + auto *funcs = hb_outline_recording_pen_get_funcs (); + + hb_font_draw_glyph (font, glyph, funcs, &hb_outline); + + if (unlikely (hb_outline.points.in_error () || + hb_outline.contours.in_error ())) + { + outline->n_points = outline->n_contours = 0; + return false; + } + + outline->n_points = hb_outline.points.length; + outline->points = wasm_runtime_module_dup_data (module_inst, + (const char *) hb_outline.points.arrayZ, + hb_outline.points.get_size ()); + outline->n_contours = hb_outline.contours.length; + outline->contours = wasm_runtime_module_dup_data (module_inst, + (const char *) hb_outline.contours.arrayZ, + hb_outline.contours.get_size ()); + + if ((outline->n_points && !outline->points) || + (!outline->n_contours && !outline->contours)) + { + outline->n_points = outline->n_contours = 0; + return false; + } + + return true; +} + }} diff --git a/src/hb-wasm-api-list.hh b/src/hb-wasm-api-list.hh index 545b2f098..4e5172450 100644 --- a/src/hb-wasm-api-list.hh +++ b/src/hb-wasm-api-list.hh @@ -78,6 +78,7 @@ static NativeSymbol _hb_wasm_native_symbols[] = NATIVE_SYMBOL ("(ii)i", font_get_glyph_v_advance), NATIVE_SYMBOL ("(iii)i", font_get_glyph_extents), NATIVE_SYMBOL ("(ii$*)", font_glyph_to_string), + NATIVE_SYMBOL ("(iii)i", font_copy_glyph_outline), /* shape */ NATIVE_SYMBOL ("(iiii$)i", shape_with), diff --git a/src/hb-wasm-api.h b/src/hb-wasm-api.h index 43327cd35..5600d431b 100644 --- a/src/hb-wasm-api.h +++ b/src/hb-wasm-api.h @@ -207,7 +207,8 @@ HB_WASM_API (position_t, font_get_glyph_v_advance) (HB_WASM_EXEC_ENV ptr_d(font_t, font), codepoint_t glyph); -typedef struct { +typedef struct +{ position_t x_bearing; position_t y_bearing; position_t width; @@ -225,9 +226,40 @@ HB_WASM_API (void, font_glyph_to_string) (HB_WASM_EXEC_ENV char *s, uint32_t size); +/* outline */ + +enum glyph_outline_point_type_t +{ + MOVE_TO, + LINE_TO, + QUADRATIC_TO, + CUBIC_TO, +}; + +typedef struct +{ + float x; + float y; + uint32_t type; +} glyph_outline_point_t; + +typedef struct +{ + uint32_t n_points; + ptr_t(glyph_outline_point_t) points; + uint32_t n_contours; + ptr_t(uint32_t) contours; +} glyph_outline_t; + +HB_WASM_API (bool_t, font_copy_glyph_outline) (HB_WASM_EXEC_ENV + ptr_d(font_t, font), + codepoint_t glyph, + ptr_d(glyph_outline_t, outline)); + /* shape */ -typedef struct { +typedef struct +{ tag_t tag; uint32_t value; uint32_t start; diff --git a/src/wasm/sample/c/shape-fallback.cc b/src/wasm/sample/c/shape-fallback.cc index 85834a1c1..335331c2c 100644 --- a/src/wasm/sample/c/shape-fallback.cc +++ b/src/wasm/sample/c/shape-fallback.cc @@ -42,6 +42,10 @@ shape (void *shape_plan, contents.info[i].codepoint = font_get_glyph (font, contents.info[i].codepoint, 0); contents.pos[i].x_advance = font_get_glyph_h_advance (font, contents.info[i].codepoint); + + glyph_outline_t outline; + font_copy_glyph_outline (font, contents.info[i].codepoint, &outline); + debugprint1 ("num outline contours", outline.n_contours); } bool_t ret = buffer_set_contents (buffer, &contents);