Skip to content

Commit

Permalink
draw to ctx (needs polishing)
Browse files Browse the repository at this point in the history
  • Loading branch information
chearon committed Jun 21, 2023
1 parent dc4e0e8 commit 7676278
Show file tree
Hide file tree
Showing 6 changed files with 117 additions and 15 deletions.
2 changes: 2 additions & 0 deletions build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ em++ \
-DHB_EXPERIMENTAL_API \
--no-entry \
-s [email protected] \
-s ERROR_ON_UNDEFINED_SYMBOLS=0 \
-s WARN_ON_UNDEFINED_SYMBOLS=0 \
-s INITIAL_MEMORY=65MB \
-o hb.wasm \
hbjs.cc
99 changes: 85 additions & 14 deletions hbjs.cc
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,18 @@ HB_BEGIN_DECLS
int
hbjs_glyph_svg (hb_font_t *font, hb_codepoint_t glyph, char *buf, unsigned buf_size);

/* imports */
void hbjs_glyph_draw_move_to(float to_x, float to_y);
void hbjs_glyph_draw_line_to(float to_x, float to_y);
void hbjs_glyph_draw_quadratic_to(float control_x, float control_y, float to_x, float to_y);
void hbjs_glyph_draw_cubic_to(
float control1_x, float control1_y,
float control2_x, float control2_y,
float to_x, float to_y);
void hbjs_glyph_draw_close_path();

void hbjs_glyph_draw(hb_font_t *font, hb_codepoint_t glyph);

unsigned
hbjs_shape_with_trace (hb_font_t *font, hb_buffer_t* buf,
char* featurestring,
Expand Down Expand Up @@ -72,23 +84,23 @@ _user_data_printf (user_data_t *data, const char *format, ...)
}

static void
move_to (hb_draw_funcs_t *dfuncs, user_data_t *draw_data, hb_draw_state_t *,
svg_move_to (hb_draw_funcs_t *dfuncs, user_data_t *draw_data, hb_draw_state_t *,
float to_x, float to_y,
void *)
{
_user_data_printf (draw_data, "M%g,%g", (double)to_x, (double)to_y);
}

static void
line_to (hb_draw_funcs_t *dfuncs, user_data_t *draw_data, hb_draw_state_t *,
svg_line_to (hb_draw_funcs_t *dfuncs, user_data_t *draw_data, hb_draw_state_t *,
float to_x, float to_y,
void *)
{
_user_data_printf (draw_data, "L%g,%g", (double)to_x, (double)to_y);
}

static void
quadratic_to (hb_draw_funcs_t *dfuncs, user_data_t *draw_data, hb_draw_state_t *,
svg_quadratic_to (hb_draw_funcs_t *dfuncs, user_data_t *draw_data, hb_draw_state_t *,
float control_x, float control_y,
float to_x, float to_y,
void *)
Expand All @@ -101,7 +113,7 @@ quadratic_to (hb_draw_funcs_t *dfuncs, user_data_t *draw_data, hb_draw_state_t *
}

static void
cubic_to (hb_draw_funcs_t *dfuncs, user_data_t *draw_data, hb_draw_state_t *,
svg_cubic_to (hb_draw_funcs_t *dfuncs, user_data_t *draw_data, hb_draw_state_t *,
float control1_x, float control1_y,
float control2_x, float control2_y,
float to_x, float to_y,
Expand All @@ -117,35 +129,94 @@ cubic_to (hb_draw_funcs_t *dfuncs, user_data_t *draw_data, hb_draw_state_t *,
}

static void
close_path (hb_draw_funcs_t *dfuncs, user_data_t *draw_data, hb_draw_state_t *, void *)
svg_close_path (hb_draw_funcs_t *dfuncs, user_data_t *draw_data, hb_draw_state_t *, void *)
{
_user_data_printf (draw_data, "Z");
}

static hb_draw_funcs_t *funcs = 0;
static hb_draw_funcs_t *svg_funcs = 0;

int
hbjs_glyph_svg (hb_font_t *font, hb_codepoint_t glyph, char *buf, unsigned buf_size)
{
if (funcs == 0) /* not the best pattern for multi-threaded apps which is not a concern here */
if (svg_funcs == 0) /* not the best pattern for multi-threaded apps which is not a concern here */
{
funcs = hb_draw_funcs_create (); /* will be leaked */
hb_draw_funcs_set_move_to_func (funcs, (hb_draw_move_to_func_t) move_to, nullptr, nullptr);
hb_draw_funcs_set_line_to_func (funcs, (hb_draw_line_to_func_t) line_to, nullptr, nullptr);
hb_draw_funcs_set_quadratic_to_func (funcs, (hb_draw_quadratic_to_func_t) quadratic_to, nullptr, nullptr);
hb_draw_funcs_set_cubic_to_func (funcs, (hb_draw_cubic_to_func_t) cubic_to, nullptr, nullptr);
hb_draw_funcs_set_close_path_func (funcs, (hb_draw_close_path_func_t) close_path, nullptr, nullptr);
svg_funcs = hb_draw_funcs_create (); /* will be leaked */
hb_draw_funcs_set_move_to_func (svg_funcs, (hb_draw_move_to_func_t) svg_move_to, nullptr, nullptr);
hb_draw_funcs_set_line_to_func (svg_funcs, (hb_draw_line_to_func_t) svg_line_to, nullptr, nullptr);
hb_draw_funcs_set_quadratic_to_func (svg_funcs, (hb_draw_quadratic_to_func_t) svg_quadratic_to, nullptr, nullptr);
hb_draw_funcs_set_cubic_to_func (svg_funcs, (hb_draw_cubic_to_func_t) svg_cubic_to, nullptr, nullptr);
hb_draw_funcs_set_close_path_func (svg_funcs, (hb_draw_close_path_func_t) svg_close_path, nullptr, nullptr);
}

user_data_t draw_data(buf, buf_size);
hb_font_get_glyph_shape (font, glyph, funcs, &draw_data);
hb_font_get_glyph_shape (font, glyph, svg_funcs, &draw_data);
if (draw_data.failure)
return -1;

buf[draw_data.consumed] = '\0';
return draw_data.consumed;
}

static void
glyph_draw_move_to (hb_draw_funcs_t *dfuncs, void *draw_data, hb_draw_state_t *,
float to_x, float to_y,
void *)
{
hbjs_glyph_draw_move_to(to_x, to_y);
}

static void
glyph_draw_line_to (hb_draw_funcs_t *dfuncs, void *draw_data, hb_draw_state_t *,
float to_x, float to_y,
void *)
{
hbjs_glyph_draw_line_to(to_x, to_y);
}

static void
glyph_draw_quadratic_to (hb_draw_funcs_t *dfuncs, void *draw_data, hb_draw_state_t *,
float control_x, float control_y,
float to_x, float to_y,
void *)
{
hbjs_glyph_draw_quadratic_to(control_x, control_y, to_x, to_y);
}

static void
glyph_draw_cubic_to (hb_draw_funcs_t *dfuncs, void *draw_data, hb_draw_state_t *,
float control1_x, float control1_y,
float control2_x, float control2_y,
float to_x, float to_y,
void *)
{
hbjs_glyph_draw_cubic_to(control1_x, control1_y, control2_x, control2_y, to_x, to_y);
}

static void
glyph_draw_close_path (hb_draw_funcs_t *dfuncs, user_data_t *draw_data, hb_draw_state_t *, void *)
{
hbjs_glyph_draw_close_path();
}

static hb_draw_funcs_t *glyph_draw_funcs = 0;

void
hbjs_glyph_draw(hb_font_t *font, hb_codepoint_t glyph)
{
if (glyph_draw_funcs == 0)
{
glyph_draw_funcs = hb_draw_funcs_create ();
hb_draw_funcs_set_move_to_func (glyph_draw_funcs, (hb_draw_move_to_func_t) glyph_draw_move_to, nullptr, nullptr);
hb_draw_funcs_set_line_to_func (glyph_draw_funcs, (hb_draw_line_to_func_t) glyph_draw_line_to, nullptr, nullptr);
hb_draw_funcs_set_quadratic_to_func (glyph_draw_funcs, (hb_draw_quadratic_to_func_t) glyph_draw_quadratic_to, nullptr, nullptr);
hb_draw_funcs_set_cubic_to_func (glyph_draw_funcs, (hb_draw_cubic_to_func_t) glyph_draw_cubic_to, nullptr, nullptr);
hb_draw_funcs_set_close_path_func (glyph_draw_funcs, (hb_draw_close_path_func_t) glyph_draw_close_path, nullptr, nullptr);
}

hb_font_get_glyph_shape (font, glyph, glyph_draw_funcs, nullptr);
}

static hb_bool_t do_trace (hb_buffer_t *buffer,
hb_font_t *font,
const char *message,
Expand Down
27 changes: 27 additions & 0 deletions hbjs.js
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,10 @@ function hbjs(instance) {
ptr: ptr,
glyphName: glyphName,
glyphToPath: glyphToPath,
drawGlyph(glyphId, ctx) {
hbjs.ctx = ctx;
exports.hbjs_glyph_draw(ptr, glyphId);
},
/**
* Return a glyph as a JSON path string
* based on format described on https://svgwg.org/specs/paths/#InterfaceSVGPathSegment
Expand Down Expand Up @@ -498,5 +502,28 @@ function hbjs(instance) {
};
};


hbjs.setCtx = function (_ctx) {
hbjs.ctx = _ctx;
};

hbjs.env = {
hbjs_glyph_draw_move_to(x, y) {
hbjs.ctx.moveTo(x, y);
},
hbjs_glyph_draw_line_to(x, y) {
hbjs.ctx.lineTo(x, y);
},
hbjs_glyph_draw_quadratic_to(control_x, control_y, to_x, to_y) {
hbjs.ctx.quadraticCurveTo(control_x, control_y, to_x, to_y);
},
hbjs_glyph_draw_cubic_to(control1_x, control1_y, control2_x, control2_y) {
hbjs.ctx.bezierCurveTo(control1_x, control1_y, control2_x, control2_y);
},
hbjs_glyph_draw_close_path() {
hbjs.ctx.closePath();
}
}

// Should be replaced with something more reliable
try { module.exports = hbjs; } catch(e) {}
1 change: 1 addition & 0 deletions hbjs.symbols
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ _hb_set_next_many
_hb_shape
_hbjs_glyph_svg
_hbjs_shape_with_trace
_hbjs_glyph_draw
_malloc
_free
_free_ptr
2 changes: 1 addition & 1 deletion index.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ var hbjs = require('./hbjs.js')
module.exports = new Promise(function (resolve, reject) {
fs.readFile(path.resolve(__dirname, 'hb.wasm'), function (err, data) {
if (err) { reject(err); return; }
WebAssembly.instantiate(data).then(function (result) {
WebAssembly.instantiate(data, {env: hbjs.env}).then(function (result) {
resolve(hbjs(result.instance));
}, reject);
});
Expand Down
1 change: 1 addition & 0 deletions types.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ declare namespace HarfbuzzJsInit {

type HbFont = {
ptr: number;
drawGlyph(gid: number, ctx: any): void;
glyphToPath(gid: number): string;
glyphToJson(gid: number): {type: string, values: number[]}[];
setScale(xScale: number, yScale: number): void;
Expand Down

0 comments on commit 7676278

Please sign in to comment.